API Lifecycle
An API lifecycle is a process of API development that covers collecting the business requirements, architect, designing, building, testing, delivering, consuming, operating, maintaining, analyzing and eventually updating or retiring an API.
The Group's Group API Lifecycle follows the API-first and contract-first core principles. It comprises of eight phases:
- Design
- Develop & Test
- Deploy
- Publish
- Operate
- Consume
- Analyze
- Update
The contract-first principle is the essential element in the lifecycle. APIs are defined in their contract before any technical implementation work. The contract drives many of the activities along the lifecycle and allows for automation in many cases. This principle ensures consistency and improves the developer experience.
API Lifecycle Governance
Each of the API lifecycle phases has its particular governance and guidelines in addition to the Core Principles which apply to every stage of the API lifecycle.
Design Phase
The design phase includes the collection and specification of business requirements, its analysis, selection of the appropriate architectural style (e.g., Web API or GraphQL API), architecture of the API, governance of API protocol, message, application-level semantics, as well as, non-functional design requirements and recommendations.
This phase also covers the API description, and tools for API design.
Finally, the authored API description is reviewed by peers and stakeholders to become a contract.
Develop & Test Phase
The develop & test phase includes the standards and guidelines for the development and testing of an API.
This phase recommends tools for API integration testing.
Deploy Phase
The deploy phase includes the guidelines for setting up the API deployment pipeline and automated API integration testing.
Publish Phase
The publish phase includes how to securely expose deployed API to the public, including access control, throttling, and operation and business analytics setups.
This phase also governs API Gateway and other API Management tools, as well as, Authentication.
Operate Phase
The operate phase includes the governance of operating and maintaining an API, availability monitoring, scaling, and support.
Consume Phase
The consume phase includes the guidelines for presenting an API to its consumers and the user support. It also includes the recommendation to API users to ensure future compatibility and scale-ability.
This phase covers the DPDHL API Repository and DPDHL Developer Portal.
Analyze Phase
The analyze phase includes the guidelines for business analytics, usage analytics, and monetization.
Update Phase
The update phase includes the API evolution governance. It also includes the requirements for updates and retirement as a special case of update to an API and communication thereof.
This phase also covers API Versioning and Change Management.
Design Phase
Selection of API Architectural Style
The selection of API Architectural Style (e.g., REST, GraphQL) should be always the function of meeting the API product requirements and achieving the target system properties. It is the tasks of the API architect to evaluate available API styles and pick the right one for the product and the desired distributed system qualities. The selection should never follow current hype marketing or technology limitations.
Every API in the scope MUST be implemented as a Web API (preferably REST API), additionally the same API MAY be also provided as a GraphQL API (i.e., always provide Web API, optionally also provide GraphQL API alongside the Web API).
The REST API Architectural following these Standards & Guidelines is the preferred API architectural style at DPDHL and should be used in the most but the simplistic use cases (e.g., scenarios when caching is not needed, API is covering just one domain, or when there is only one client per one server - e.g. API for a web app).
Use the following flowchart to guide decision between the REST, RPC and Tunnelling/Query API style:
(This flowchart is refined version of the Picking the right API Paradigm chart with additional clarifications and reflecting DPDHL specifics)
Refer to the recommended reading for a deep-dive into API styles their benefits and drawbacks.
Recommended Reading:
- REST vs. GraphQL: A Critical Review
- GraphQL vs REST: Overview
- A nonsense GraphQL and REST comparison
- Picking the right API Paradigm
Web APIs
Web API Design Maturity
Design of a Web API MUST, at least, follow the Resource-based modeling – Web API Design Maturity Model Level 2, i.e., the API MUST be designed along resources and relations between resources.
Web API (Amundsen) Design Maturity Model categorizes the design of an API into four levels and focuses on the API description documents.
Each of the levels has implications on the properties of the designed system.
At Level 2, the API is designed along resources and relations between them. Proper resource-based design leads to decoupling from internal models (database or application) and enables for further extensibility and evolution.
(Source: Amundsen Maturity Model)
Web API Design Implementation Maturity
Web APIs MUST follow the HTTP protocol semantics - Richardson Maturity Model Level 2.
The Richardson Maturity Model categorizes different web services designs into four levels and focuses on the API response documents.
Each of the levels has implications on the qualities of the resulting distributed systems.
APIs that follow at least the Richardson Maturity Model Level 2 benefit from the features of the HTTP protocol such as caching, performance and stability. APIs on lower levels lack the cache ability and scalability.
(Source: Richardson Maturity Model)
Layers of Design-time Governance
In addition to the overall API design and design implementation maturity requirements the design-time governance comprises of the following layers of standards and guidelines:
- Protocol-level governance
- Message format governance
- Application-level semantics governance
- Design patterns governance
Design Review
The result of the Design Phase of the API Lifecycle is the API Description. This description MUST be reviewed by peers and stakeholders before it's accepted. Once an API Description is reviewed and approved it becomes the contract between all API lifecycle participants.
Protocols
HTTP/1.1
Every API MUST support the HTTP/1.1 protocol, and MUST adhere to its semantic.
HTTP/2
An API MAY support the HTTP/2 protocol.
TLS
Every API SHOULD require secure connections with TLS 1.2 (TLS 1.3). Any non-TLS requests SHOULD be ignored. In HTTP environments where this is not possible, a non-TLS request SHOULD result in the 403 Forbidden response.
Message Format
Response Message Format
Every API MUST provide JSON (application/json
) representation of the resources.
An API MAY provide other (e.g., XML – application/xml
) representation of the resources in addition to the JSON representation.
The response message format MUST follow the concepts of RESTful JSON to communicate the links.
JSON (or JSON-based) resource representation is the de facto standard of modern Web APIs. It's a lightweight and more accessible format, suitable for consumption by web and mobile clients.
An API (resource) might have more than just one representation. The client can choose (ask) for a particular representation using the mechanism known as content-negotiation.
Error Response Format
The application/problem+json
(Problem Detail) format MUST be used to communicate details about an error when a JSON representation has been requested.
JSON Message Format Conventions
JSON-based message formats (e.g., application/json
, application/problem+json
) SHOULD follow these guidelines:
- Boolean fields SHOULD NOT be of
null
value- SHOULD use
false
instead ofnull
- SHOULD use
- Fields with null value SHOULD be omitted completely
- Empty arrays and objects SHOULD NOT be
null
- SHOULD use
[]
or{}
instead
- SHOULD use
API Design Patterns
This section covers the governance of selected design patterns. The patterns are added upon the request of the teams and architects. It's expected that this section to grow over the time.
Web APIs Design Patterns
The following subsections covers some common patterns to be considered when designing Web APIs.
Pagination
A collection resource SHOULD provide the standard first
, last
, next
and prev
links for navigation within the collection. Besides, the resource SHOULD support the offset
and limit
query parameters to support the navigation in the collection.
Example
The Collection of Orders using the collection navigation link and offset
and limit
query parameters:
{
"url": { "href": "/orders?offset=100&limit=10" },
"prev_url": { "href": "/orders?offset=90&limit=10" },
"next_url": { "href": "/orders?offset=110&limit=10" },
"first_url": { "href": "/orders?limit=10" },
"last_url": { "href": "/orders?offset=900&limit=10" },
"total_count": 910,
"orders": [
]
}
Naming Conventions
General Conventions
The following general rules apply to names, identifiers and descriptions authored or produced thorough the API Lifecycle.
- SHOULD use American English
- SHOULD NOT use acronyms
- SHOULD NOT use abbreviations
- SHOULD use
lowerCamelCase
unless stated otherwise
These rules might be subject to exceptions in specific naming conventions listed below.
HTTP Protocol
Conventions related to the application of HTTP protocol.
URI
URI SHOULD prefer lowercase with words separated by the hyphen (-
). URI SHOULD NOT have trailing slash (/
). URI SHOULD use api.dhl.com
host for group-wide APIs. (e.g., /system-orders/1234
).
Keep in mind that per these Standards & Guidelines, divisional API URIs MUST NOT clash with group-wide APIs URIs.
Keep in mind URI is case-sensitive (RFC7230).
URI Template Variables
URI Template Variables SHOULD follow the RFC6570 standard (ALPHA
/ DIGIT
/ _
/ pct-encoded
),
SHOULD prefer ALPHA
/ DIGIT
.
URI Query & Fragment
URI Query & Fragment identifiers SHOULD NOT clash with reserved identifiers (e.g., fields
, embedded
, limit
, offset
)
Relation Type Identifier
Relation type identifiers SHOULD use lowercase with words separated by the hyphen (-
) (e.g., fulfillment-provider
)
HTTP Headers
HTTP header names SHOULD use Hyphenated-Pascal-Case
. An HTTP header name SHOULD NOT start with X-
(RFC6648).
Representation formats
Conventions covering the naming of fields in resource representation formats.
JSON Format field naming conventions
- SHOULD follow RESTful JSON conventions
- SHOULD prefer
lowerCamelCase
, - SHOULD use ASCII alphanumeric characters
- MAY use underscore (
_
), at (@
), or dollar sign ($
) at the start of the field name - MAY use hyphen in (
-
) in relation type identifiers - Array field names SHOULD be plural (e.g.,
"orders": []
)
Web APIs OpenAPI Naming Conventions
Conventions covering the authoring of API description-OpenAPI specification.
API Name
API Name in OAS (info.title
) SHOULD contain team and version information for search and ordering purposes.
However, these information (team, version) SHOULD NOT be exposed to consumers (e.g. on a developer portal).
- SHOULD use Title Case
- SHOULD be in format:
API Name [Domain|BU|Team] (version name)
Example
Orders API [EXP] (development)
, Orders API [EXP] (production)
, Orders API [DSC]
Resource & Action Names
Resource and action names (paths.<path>.x-summary
and paths.<path>.<method>summary
) SHOULD use Title Case
.
Example
List of Orders
, Create Order
OpenAPI Specification Identifiers
Every OAS identifier SHOULD follow the General Conventions.
Reserved Identifiers
An API SHOULD NOT use following identifiers except for their intended use:
-
RESTful JSON Representation format
url
<relation-type-identifier>Url
-
URI Query Parameters
offset
(pagination)limit
(pagination)fields
(sparse fieldset)embedded
(embedding related resources)
NOTE: Only offset and limit are currently specified in API Standards & Guidelines
Develop & Test Phase
Web APIs Contract Testing
An API implementation SHOULD be tested against its API Description. The contract tests SHOULD be done using an established testing framework, e.g. the Dredd HTTP API Testing framework.
Running tests with Dredd verifies that the contract in the form of API Description is fulfilled. Furthermore, since the API description is authored before the API implementation (API-first, contract-first) the contract represents the tests and thus follows the principles of test-driven development.
Deploy Phase
Web APIs Automated Contract Testing
The API implementation pipeline SHOULD be set-up in a way that whenever there is a change to the service implementation or the related API contract (API description) a new test run of contract tests is executed. The service MUST NOT be deployed until all tests pass successfully.
Publish Phase
URIs
An API URI SHOULD not contain internal terms and references in the URI structure (e.g., application names). Divisional APIs MUST NOT use URIs which could be confused with group-wide or other division's offerings and use the established divisional URI base URLs.
Further principles around URIs are noted in Update phase section.
Authentication
Any use of a public API MUST be authenticated by, at least, one of the following methods:
- OAuth2
- OpenID Connect
- API Key
OAuth2 is the preferred method for scenarios that do not need to carry user-identity. If a user identity is required, the API SHOULD be secured using the OpenID connect.
Securing APIs by API Key SHOULD be considered only for accessing publicly available information.
Indication of Use
- Use API Key to identify or authenticate calling client application
- Use OAuth2 to authorize resource access in name of a specific user
- Use OpenID Connect for user authentication, identification and for sharing details of customers
Update Phase
Web API Versioning
Note this entire section is specific to Web APIs (and RESTful APIs in particular).
Type of Change
All types of changes that are made should be backward compatible. A backward-compatible change is a change to:
- Resource identifier (URI) including any query parameters and their semantics
- Resource metadata (HTTP headers)
- Action the resource affords (HTTP Methods), /hereafter affordance/
- Relation with other resources (Links)
- Representation format (HTTP request and response bodies)
that follows the Rules for Extending:
- One MUST NOT take anything away
- One MUST NOT change processing rules
- One MUST NOT make optional things required
- Anything one adds MUST be optional
A change that violates any of the Rules for Extending is a backward-incompatible change.
Backward-compatible Changes
A change that does not violates the Rules for Extending SHOULD be applied directly to the original variant.
Backward-incompatible Changes
A change that would violate the Rules for Extending MUST result in a new resource variant. Existing resource variant MUST be preserved.
A change to representation format SHOULD NOT result in a new resource variant. Instead it SHOULD follow the Representation Format Change practice (see section below).
The fundamental principle is that you can’t break existing clients, because you don’t know what they implement, and you don’t control them. In doing so, you need to turn a backward-incompatible change into a compatible one.
If there are multiple substantial changes, a new version of the API MAY be published. If a new variant of the resource cannot be created, a new version of the API SHOULD be published. See the "Substantial API Changes" section below for details on publishing a new API version.
Example
Currently, optional URI Query Parameter first
on an existing resource /greeting?first=John&last=Appleseed
needs to be made required.
Since this change violates the 3rd rule of extending and could break existing clients a new variant of the resource is created with different URI /named-greeting?first=John&last=Appleseed
.
Identifier Stability
A change MUST NOT affect existing resource identifiers (URIs).
A resource identifier MUST NOT contain a semantic version to convey the variant of the resource. The exception is the resource identifier base path which MAY include API semantic version (as discussed in the "Substantial API Changes" section below).
Concern Separation & Version in Resource Identifier
Information such as version of the resource (e.g. v2
in /greeting-v2
), format of the resource representation (e.g. .json
in /greeting.json
), metadata about the resource representation (e.g. utf8
in /greeting-utf8
) etc. should not be part of the identifier to enable client-server decoupling.
Example
Continuing in the previous example, the new variant of the "greeting" resource should not include the semantic version in its URI. The original "greeting" resource and its URI (/greeting
) must remain untouched and available after the new variant is added.
Incorrect Example
https://api.dhl.com/myapi/greeting-v2?first=John&last=Appleseed
Correct Example - API Change Management
https://api.dhl.com/myapi/named-greeting?first=John&last=Appleseed
Correct Example - API Semantic Versioning
https://api.dhl.com/myapi/v2/named-greeting?first=John&last=Appleseed
Representation Format Change
A representation format is the serialization format (media type) used in request and response bodies, and typically it represents a resource or its part, possibly with hypermedia controls.
If a change to a representation format can't follow the Rules for Extending the representation format media type (version) MUST be changed. If the media type has been changed the previous media type, MUST be still available via Content Negotiation.
If the media type conveys the version parameter, the version parameter MUST follow Semantic versioning.
Example
Media type before a breaking change:
application/vnd.example.resource+json; version=2
Media type after a breaking change:
application/vnd.example.resource+json; version=3
API Description Versioning
API Description in the OpenAPI specification format MUST have the version
field. The version
field MUST follow Semantic versioning:
*Given a version number MAJOR.MINOR.PATCH, increment the:
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backward-compatible manner
- PATCH version when you make backward-compatible bug fixes
The API Description version MUST be updated accordingly to API design change.
Substantial API Changes
If there were many substantial backward-incompatible changes to an API, a new API version MAY be published instead of opting for the API change management (that is, the evolutionary approach of individual resources and resource variants).
If a new version of the API is published, the original version of the API MUST be maintained.
The new API version MAY use semantic versioning (e.g. v2
) in the base URL.
Retire
Resources and Affordances
A resource or affordance MAY be retired. Analytics tools SHOULD be used to evaluate whether the resource or affordance is used by any of the API consumers. Prior to its retirement the resource or affordance SHOULD be marked as deprecated or completely phased out from the API documentation for new API users.
In any case, the retirement MUST be communicated to API users.
If a new variant replaces a resource or affordance, a redirection SHOULD be provided.
Entire API
At the end of its life, an entire API MAY be retired. The retirement of an API MUST be communicated to its current users. Where possible, a migration path SHOULD be provided.