mirror of
https://github.com/adidas/api-guidelines.git
synced 2025-10-25 15:19:19 +00:00
GitBook: [master] 69 pages modified
This commit is contained in:
4
rest-api-guidelines/evolution/README.md
Normal file
4
rest-api-guidelines/evolution/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Evolution
|
||||
|
||||
Evolution qualities, such as testability, maintainability, extensibility, and scalability.
|
||||
|
||||
132
rest-api-guidelines/evolution/naming-conventions.md
Normal file
132
rest-api-guidelines/evolution/naming-conventions.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# Naming Conventions
|
||||
|
||||
## General Naming Rules
|
||||
|
||||
* Use American English
|
||||
* Don't use acronyms
|
||||
* Use `camelCase` unless stated otherwise
|
||||
* Reconcile terms with adidas CDM
|
||||
|
||||
Every identifier **MUST** be in American English and written in `lowercase`. An identifier **SHOULD NOT** contain acronyms. CamelCase \(`camelCase`\) **MUST** be used to delimit combined words.
|
||||
|
||||
## URI
|
||||
|
||||
Every URI **MUST** follow the General Rules except for the `camelCase` rule. Instead, a hyphen \(`-`\) **SHOULD** be used to delimit combined words \(kebab-case\). Besides, a URI **MUST NOT** end with a trailing slash \(`/`\).
|
||||
|
||||
#### Example
|
||||
|
||||
A well-formed URI:
|
||||
|
||||
```text
|
||||
/system-orders/1234/author
|
||||
```
|
||||
|
||||
### Query Parameters and Path Fragments
|
||||
|
||||
Every URI query parameter or fragment **MUST** follow the General Rules. Also, they **MUST NOT** clash with the [reserved query parameter names](reserved-identifiers.md#query-parameters).
|
||||
|
||||
### URI Template Variables
|
||||
|
||||
In addition to General Naming Rules, URI Template Variable names **MUST** follow the [RFC6570](https://tools.ietf.org/html/rfc6570#section-2.3). That is, the variable names can consist only from `ALPHA / DIGIT / "_" / pct-encoded`.
|
||||
|
||||
> NOTE: Per RFC6570 Hyphen \(`-`\) is NOT legal URI Template variable name character.
|
||||
|
||||
#### Example
|
||||
|
||||
A well-formed URI Template Variable:
|
||||
|
||||
```text
|
||||
/system-orders/{orderId}/author
|
||||
```
|
||||
|
||||
## Representation Format Fields
|
||||
|
||||
Every representation format field **MUST** conform to the General Naming Rules.
|
||||
|
||||
#### Example
|
||||
|
||||
A well-formed resource representation:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"_links": {
|
||||
"self": {
|
||||
"href": "/orders/1234"
|
||||
},
|
||||
"author": {
|
||||
"href": "/users/john"
|
||||
}
|
||||
},
|
||||
"orderNumber": 1234,
|
||||
"itemCount": 42,
|
||||
"status": "pending"
|
||||
}
|
||||
```
|
||||
|
||||
## Relation Type Identifier
|
||||
|
||||
Every custom [relation identifier](https://github.com/for-GET/know-your-http-well/blob/master/relations.md) **MUST** be in `lowercase` with words separated by the hyphen \(`-`\).
|
||||
|
||||
#### Example
|
||||
|
||||
A well-formed resource representation with custom relation `fulfillment-provider`:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"_links": {
|
||||
"fulfillment-provider": {
|
||||
"href": "/users/natalie"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## HTTP Headers
|
||||
|
||||
Every HTTP Header should use `Hyphenated-Pascal-Case`. A custom HTTP Header **SHOULD NOT** start with `X-` \([RFC6648](https://tools.ietf.org/html/rfc6648)\).
|
||||
|
||||
#### Example
|
||||
|
||||
```text
|
||||
Order-Metadata-Header: 42
|
||||
```
|
||||
|
||||
## API Description
|
||||
|
||||
Naming conventions within API Description document.
|
||||
|
||||
### API Name
|
||||
|
||||
Every API Description API name **MUST** start with API domain enclosed in square brackets \(e.g. `[API Domain] My API`\). Words **MUST** be separated by space.
|
||||
|
||||
#### Example
|
||||
|
||||
```yaml
|
||||
swagger: '2.0'
|
||||
info:
|
||||
version: '1.0.0'
|
||||
title: '[Demo] Orders API'
|
||||
```
|
||||
|
||||
### Resource Name
|
||||
|
||||
Every resource **MUST** have a name \(defined by `x-summary` field\). Resource name **MUST** be in `Title Case`. Words **MUST** be separated by a space.
|
||||
|
||||
#### Example
|
||||
|
||||
```yaml
|
||||
/orders:
|
||||
x-summary: List of Orders
|
||||
```
|
||||
|
||||
### Action Name
|
||||
|
||||
Every action \(operation\) **MUST** have a name \(defined by `summary` field\). Action name **MUST** be in `Title Case`. Words **MUST** be separated by a space.
|
||||
|
||||
#### Example
|
||||
|
||||
```yaml
|
||||
get:
|
||||
summary: Retrieve List of Orders
|
||||
```
|
||||
|
||||
38
rest-api-guidelines/evolution/phasing-out-old-versions.md
Normal file
38
rest-api-guidelines/evolution/phasing-out-old-versions.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Phasing out Old Versions
|
||||
|
||||
An older resource variant or action **MAY** be phased out and eventually removed providing clients were given enough time to accommodate for the change.
|
||||
|
||||
Whether a resource or action can be phased out and removed completely depends on the nature of the API and the importance of existing integrations.
|
||||
|
||||
If an interface might be phased out it **MUST** follow the Phasing out Outline as specified in these guidelines.
|
||||
|
||||
> The gist is to never break existing clients. As soon as there is a breaking change a new resource variant should be created leaving the original intact to not break existing integrations. However, over the time it might be desired to remove older, unused variants.
|
||||
|
||||
### Phasing out Outline
|
||||
|
||||
#### 1. Mark as Deprecated
|
||||
|
||||
The deprecation mark **SHOULD** happen both at runtime and in the documentation.
|
||||
|
||||
For the runtime deprecation notice the [HTTP Sunset Header](https://tools.ietf.org/id/draft-wilde-sunset-header-03.html) **MUST** be used. For the documentation, the resource or action **MUST** be clearly marked in its description as deprecated.
|
||||
|
||||
#### 2. Inform Users
|
||||
|
||||
Existing API users **MUST** be noticed by available means about the deprecation of the interface. They **SHOULD** be informed about what are the alternatives to using the deprecated functionality and what is the migration path.
|
||||
|
||||
#### 3. Remove Documentation of the Deprecated Interface
|
||||
|
||||
Eventually, the part of API documentation describing the deprecated interface **MAY** be removed or hidden to prevent new users from using the deprecated resources or actions.
|
||||
|
||||
#### 4. Final Notice
|
||||
|
||||
After a sufficient grace period a final deprecation notice **SHOULD** be issued.
|
||||
|
||||
#### 5. Remove Deprecated Interface
|
||||
|
||||
When there are no users using the deprecated interface, the interface **MAY** be decommissioned. A deprecated resource or action **MUST NOT** be removed if there are known existing integrations using it.
|
||||
|
||||
Based one the nature of migration path a redirect to a new variant **SHOULD** be provided.
|
||||
|
||||
> Phasing-out, depends on the importance of the APIs and its audience, for business-critical APIs, one never want to risk removing anything. For example [Stripe.com](http://stripe.com/) maintain all past versions. For other, less critical APIs, or APIs where one control its client\(s\), one can be more relaxed about removing deprecated resources.
|
||||
|
||||
16
rest-api-guidelines/evolution/reserved-identifiers.md
Normal file
16
rest-api-guidelines/evolution/reserved-identifiers.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Reserved Identifiers
|
||||
|
||||
The list of all reserved identifiers or identifiers with special meaning.
|
||||
|
||||
## Representation Format Fields
|
||||
|
||||
* `_links` - [HAL](../message/hal.md)
|
||||
* `_embedded` - [HAL](../message/hal.md)
|
||||
|
||||
## Query Parameters
|
||||
|
||||
* `fields`- [Choosing Fields & Embedded Resources](../execution/choosing-fields-and-embedded-resoruces.md)
|
||||
* `embedded` - [Choosing Fields & Embedded Resources](../execution/choosing-fields-and-embedded-resoruces.md)
|
||||
* `offset` - [Pagination](../execution/pagination.md)
|
||||
* `limit`- [Pagination](../execution/pagination.md)
|
||||
|
||||
10
rest-api-guidelines/evolution/uri-structure.md
Normal file
10
rest-api-guidelines/evolution/uri-structure.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# URI Structure
|
||||
|
||||
URI is meant to express a **identity of a resource**. URI is an identifier and it **MUST NOT** convey any other information.
|
||||
|
||||
The API design process **MUST NOT** start with the design of URIs. Contrary, the URI **SHOULD** be amongst the last few things added to the API design.
|
||||
|
||||
At adidas, URIs are subject to [naming conventions](naming-conventions.md).
|
||||
|
||||
To read more about the problematics refer to [RFC 7320: URI Design and Ownership](https://tools.ietf.org/html/rfc7320).
|
||||
|
||||
100
rest-api-guidelines/evolution/versioning.md
Normal file
100
rest-api-guidelines/evolution/versioning.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Changes and Versioning
|
||||
|
||||
> _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 backwards-incompatible change into a compatible one._
|
||||
>
|
||||
> _–_ [_Mark Nottingham_](https://www.mnot.net/blog/2011/10/25/web_api_versioning_smackdown)
|
||||
|
||||
Any change to an API **MUST NOT** break existing clients.
|
||||
|
||||
Any change to:
|
||||
1. **Resource identifier** \(resource name / URI\) including any **query parameters** and their semantics
|
||||
2. **Resource metadata** \(e.g. HTTP headers\)
|
||||
3. **Action** the resource affords \(e.g. available HTTP Methods\)
|
||||
4. **Relation** with other resources \(e.g Links\)
|
||||
5. **Representation format** \(e.g. HTTP request and response bodies\)
|
||||
|
||||
**MUST** follow the [**Rules for Extending**](../../general-guidelines/rules-for-extending.md).
|
||||
|
||||
## Identifier Stability \(No URI Versioning\)
|
||||
|
||||
A change **MUST NOT** affect **existing** resource identifiers \(name / URI\). Furthermore, a resource identifier **MUST NOT** contain a semantic version to convey a version of resource or its representation format.
|
||||
|
||||
> _The reason to make a real REST API is to get evolvability … a "v1" is a .... to your API customers, indicating RPC/HTTP \(not REST\)_
|
||||
>
|
||||
> _–_ [_Roy T. Fielding_](https://twitter.com/fielding/status/376835835670167552)
|
||||
|
||||
#### Example
|
||||
|
||||
Adding a new action to existing resource with identifier `/greeting` doesn't change its identifier to `/v2/greeting` \(or `/greeting-with-new-action` etc.\).
|
||||
|
||||
## Backward-incompatible Changes
|
||||
|
||||
A change to _resource identifier_, _resource metadata_, _resource actions_ and _resource relations_ that can't follow the [Rules for Extending](../../general-guidelines/rules-for-extending.md) **MUST** result into a **new resource variant**. Existing resource variant **MUST** be preserved.
|
||||
|
||||
A change to _representation format_ **SHOULD NOT** result into a new resource variant.
|
||||
|
||||
#### 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`.
|
||||
|
||||
### Representation Format Changes
|
||||
|
||||
> 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 additional hypermedia controls.
|
||||
|
||||
If a change can't follow the Rules for Extending the representation format media type **MUST** be changed. If the media type has been changed the previous media type, **MUST** be available via [Content Negotiation](../message/content-negotiation.md).
|
||||
|
||||
If the media type conveys the version parameter, the version parameter **SHOULD** follow [Semantic versioning](http://semver.org/).
|
||||
|
||||
#### Example
|
||||
|
||||
Media type _before_ a breaking change:
|
||||
|
||||
```text
|
||||
application/vnd.example.resource+json; version=2
|
||||
```
|
||||
|
||||
Media type _after_ a breaking change:
|
||||
|
||||
```text
|
||||
application/vnd.example.resource+json; version=3
|
||||
```
|
||||
|
||||
> NOTE: In the case of technical limitations with semi-colon separated HTTP header values, the semantic version MAY be incorporated in the media type identifier, for example: `application/vnd.example.resource.v2+json` However, the use of semicolon-separated version information is preferred.
|
||||
|
||||
## API Description Versioning
|
||||
|
||||
API Description in the OpenAPI specification format **MUST** have the `version` field. The `version` field **MUST** follow [Semantic versioning](http://semver.org/):
|
||||
|
||||
> 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 **backwards-compatible** manner
|
||||
> * PATCH version when you make **backwards-compatible bug fixes**
|
||||
|
||||
The API Description version **SHOULD** be updated accordingly to API design change.
|
||||
|
||||
#### Example
|
||||
|
||||
Following API Description
|
||||
|
||||
```yaml
|
||||
swagger: '2.0'
|
||||
info:
|
||||
version: '2.1.3'
|
||||
title: '[Demo] Inventory API'
|
||||
description: 'Inventory service API'
|
||||
```
|
||||
|
||||
Has MAJOR version 2, MINOR version 1 and PATCH version 3.
|
||||
|
||||
#### Demo
|
||||
|
||||
API description \(OAS2\) files demonstrating a proposal of an backward-incompatible change turned into a backward compatible change are available at [Bitbucket \(diff\) ](https://bitbucket.org/apidesigner/demo-versioning-api/pull-requests/1/add-name-parameter/diff)and documented in Apiary:
|
||||
|
||||
* [Production version](https://demoversioningproduction.docs.apiary.io/#) as being consumed by clients
|
||||
* [Development version](https://demoversioningdevelopment.docs.apiary.io/#) proposing a backward incompatible change
|
||||
|
||||
#### Recommended Reading
|
||||
|
||||
* [Evolving HTTP APIs](https://www.mnot.net/blog/2012/12/04/api-evolution)
|
||||
|
||||
Reference in New Issue
Block a user