GitBook: [master] 102 pages and one asset modified

This commit is contained in:
apidesigner
2018-07-23 07:49:01 +00:00
committed by gitbook-bot
parent af88d15fd0
commit 3b81882249
68 changed files with 850 additions and 712 deletions

View File

@@ -0,0 +1,2 @@
# Functionality

View File

@@ -0,0 +1,6 @@
# Application
Every API SHOULD use company terms for resource names, relation names and representation message field names.
Also, every API MUST follow the [naming conventions](./).

View File

@@ -0,0 +1,45 @@
# Common Data Types
## Date and Time Format
Date and Time **MUST** always conform to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format e.g.: `2017-06-21T14:07:17Z` \(date time\) or `2017-06-21` \(date\), it **MUST** use the UTC \(without time offsets\).
## Duration Format
Duration format **MUST** conform to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard e.g.: `P3Y6M4DT12H30M5S` \(three years, six months, four days, twelve hours, thirty minutes, and five seconds\).
## Time Interval Format
Time Interval format **MUST** conform to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard e.g.: `2007-03-01T13:00:00Z/2008-05-11T15:30:00Z`.
## Standard Time Stamps
Where applicable, a resource representation **SHOULD** contain the standard timestamps:
* `createdAt`
* `updatedAt`
* `finishedAt`
### Example
```javascript
{
"createdAt": "2017-01-01T12:00:00Z",
"updatedAt": "2017-01-01T13:00:00Z",
...
}
```
## Language Code Format
Language codes **MUST** conform to the [ISO 639](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) e.g.: `en` for English.
## Country Code Format
Country codes **MUST** conform to the [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) e.g.: `DE` for Germany.
## Currency Format
Currency codes **MUST** conform to the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) e.g.: `EUR` for Euro.

View File

@@ -0,0 +1,10 @@
# Corporate Data Model
The design of application data model **MUST** consider the application use cases, as well as the upstream and downstream systems, use cases.
The design of the data model of an application **MUST** consider the [adidas Corporate Data Model](https://collaboration.adidas-group.com/sites/CS-GDM/Corporate%20Data%20Dictionary/Data%20Dictionary.htm) \(internal link\).
Different names for entities and attributes **MAY** be used **ONLY** if the **CDM** is not including them. If a different name is introduced then it **MUST** be included in the **CDM**.
The consistency of the names of entities and attributes across the whole application **MUST** be maintained.

View File

@@ -0,0 +1,4 @@
# Message
This section covers the message format governance.

View File

@@ -0,0 +1,30 @@
# Content Negotiation
Every API **MUST** implement and every API Consumer **MUST** use the [HTTP content negotiation](https://tools.ietf.org/html/rfc7231#section-3.4) where a representation of a resource is requested.
> NOTE: The content negotiation plays the key role in evolving an API, **change management and versioning**.
## Example
A client is programmed to understand the `application/vnd.example.resource+json; version=2` message format semantics. The client requests a representation of the `/greeting` resource in desired the media type \(including its version\) from the server:
```text
GET /greeting HTTP/1.1
Accept: application/vnd.example.resource+json; version=2
...
```
The server can provide only a newer version of the requested media type `version=2.1.3`. But since the newer version is backward compatible with the requested `version=2` \(related: Changes & Versioning\) it can satisfy the request and responds:
```text
HTTP/1.1 200 OK
Content-Type: application/vnd.example.resource+json; version=2.1.3
...
```
> NOTE: A server that doesn't have the requested representation media type available MUST respond with the HTTP Status Code **406 Not Acceptable**.
>
> NOTE: A server MAY have multiple choices available and MAY respond with the **300 Multiple Choices** response. In which case client SHOULD choose from the presented choices.
>
> You can read more about content negotiation at [MDN Content negotiation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation).

View File

@@ -0,0 +1,126 @@
# Problem Detail
The [`application/problem+json`](https://tools.ietf.org/html/rfc7807) \(Problem Detail\) **MUST** be used to communicate details about an error.
Problem Detail is intended for use with the HTTP status codes 4xx and 5xx. Problem Detail **MUST NOT** be used with 2xx status code responses.
At the minimum, any Problem Detail response **MUST** have the `title` and `detail` fields.
### Example
```javascript
{
"title": "Authentication required",
"detail": "Missing authentication credentials for the Greeting resource."
}
```
## Optional Fields
It **SHOULD** has the `type` field with the identifier of the error, besides it **MAY** have the `instance` field with the URI of the resource in question. If the Problem Detail response has the `status` field it **MUST** have the same value as HTTP Status code from of the response.
```javascript
{
"type": "https://adidas-group.com/problems/scv/unauthorized",
"title": "Authentication required",
"detail": "Missing authentication credentials for the Greeting resource.",
"instance": "/greeting",
"status": 401
}
```
> NOTE: The `type` field is an identifier, and as such it **MAY** be used to denote additional error codes. Keep in mind that the identifier should be a URI.
## Additional Fields
If needed, the Problem Detail **MAY** include additional fields, refer to [RFC7807](https://tools.ietf.org/html/rfc7807) for details.
## Validation Errors
When necessary, a Problem Detail response **MAY** include additional error details about the problems that have occurred.
These additional errors **MUST** be under the `errors` and **MUST** follow the Problem Detail structure.
### Example
Request:
```text
POST /my-resource HTTP/1.1
Content-Type: application/json
{
"age": -32,
"color": "cyan"
}
```
Response:
```text
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
Content-Language: en
{
"type": "https://example.net/validation_error",
"title": "Your request parameters didn't validate.",
"instance": "/my-resource",
"status": 400,
"errors": [
{
"type": "https://example.net/invalid_params",
"instance": "/age",
"title": "Invalid Parameter",
"detail": "age must be a positive integer"
},
{
"type": "https://example.net/invalid_params",
"instance": "/color",
"title": "Invalid Parameter",
"detail": "color must be 'green', 'red' or 'blue'"
}
]
}
```
## Problem Detail and Content Negotiation
### Example
A request is made to retrieve a resource representation:
```text
GET /greeting HTTP/1.1
Accept: application/hal+json
```
However, in order to make this request, the client needs to be authorized. Since the request is made without the authorization credentials the **401 Unauthorized** response is returned together with details using the `application/problem+json` media type:
```text
HTTP/1.1 401 Unauthorized
Content-Type: application/problem+json
Content-Language: en
{
"type": "https://adidas-group.com/problems/scv/unauthorized",
"title": "Authentication required",
"detail": "Missing authentication credentials for the Greeting resource.",
"instance": "/greeting",
"status": 401
}
```
## No Stack Traces or Server Logs
> _Problem details are not a debugging tool for the underlying implementation; rather, they are a way to expose greater detail about the HTTP interface itself._
>
> __ [_RFC7807_](https://tools.ietf.org/html/rfc7807)
A Problem Detail response **MUST NOT** contain a program stack trace or server log for debugging purposes. Instead, provide a `logref` field with reference to the particular server log.
## Working with Problem Detail
There are a whole plethora of libraries working with Problem Detail, for example, see [Zalando / Problem](https://github.com/zalando/problem) \(Java\).

View File

@@ -0,0 +1,72 @@
# Foreign Key Relations
## Link or Embed Foreign Key Relation
When a resource representation includes relation with another \(foreign\) resource, the relation **MUST** be expressed as a link relation or embed the related resource.
### Example
Use:
```javascript
{
"_links": {
"author": { "href": "/users/john" }
...
}
...
}
```
or:
```javascript
{
...
"_embedded": {
"author": {
"_links": { "self": "/users/john" },
"name": "John Appleseed",
"email": "john@apple.com"
}
}
}
```
instead:
```javascript
{
...
"authorHref": "/users/john"
}
```
## Nest Foreign Key Relation
If a foreign object has another identifier, but URI or the foreign object isn't a resource, the object **MUST** be nested.
### Example
Use:
```javascript
{
"author": {
"id": "1234",
"name": "John Appleseed",
"email": "john@apple.com"
}
}
```
instead:
```javascript
{
"authorId": "1234"
}
```
> NOTE: As a rule of thumb, in an HTTP message body, there SHOULD NOT be any field with trailing "\_id," "\_href," "\_url" etc. in its name.

View File

@@ -0,0 +1,119 @@
# HAL
The [`application/hal+json`](http://stateless.co/hal_specification.html) \(HAL\) **MUST** be used as the representation format of a resource.
## Introduction to HAL
> _HAL is a simple format that gives a consistent and easy way to hyperlink between resources in your API._
This document is an informal introduction to the HAL media type. For more details see [HAL - Hypertext Application Language Specification](http://stateless.co/hal_specification.html).
## Simple Document Example
The simplest Hal document looks like an empty JSON \(it is an empty JSON!\):
```javascript
{
}
```
A document representing a "Greeting" resource might look like:
```javascript
{
"message": "Hello World!",
"_links": {
"self": {
"href": "/greeting"
}
}
}
```
The field `_links` has a special meaning in HAL. It denotes a list of link relations - a pair of a relation identifier and a link \(URI\).
These link relations are used to express the relation of a resource with other resources.
In our case the "Greeting" resource isn't related to other resources but itself, hence the `self` relation pointing to the Greeting resource.
> NOTE: It is **customary** for every resource representation to include the `self` link relation.
>
> NOTE: The href **MUST** always be **relative path to the API root** \(e.g. without the host and scheme\).
## Relation Example
A more complex document example could be an "Order" resource that has a related resource "Author" \(a person who created the order. It might look like:
```javascript
{
"_links": {
"self": {
"href": "/orders/1234"
},
"author": {
"href": "/users/john"
}
},
"orderNumber": 1234,
"itemCount": 42,
"status": "pending"
}
```
## Embedding Example
Let's assume there is an "Orders" resource which is a collection of all orders from different authors. There is the relation between the Orders resource and possibly many Order resources.
We could express this in the `_links` object using the `order` relation, but sometimes it is practical to "embed" \(entirely or partially\) related resources representations in the originating resource representation. For a scenario like this HAL offers the `_embedded` field.
The `_embedded` field's object just contains the related resources HAL representations:
```javascript
{
"_links": {
"self": { "href": "/orders" }
},
"_embedded": {
"order": [
{
"_links": {
"self": { "href": "/orders/1" }
},
"orderNumber": "1",
"status": "pending"
},
{
"_links": {
"self": { "href": "/orders/2" }
},
"orderNumber": "2",
"status": "cancelled"
}
]
}
}
```
It is important to understand that embedded resource representation might be only **partial** and might also contain their own embedded resources.
The embedded resource representation should be used as a **convenience** function \(e.g. to reduce the initial number of calls needed at application launch\).
Where a full and up-to-date representation of a resource is needed the link relation should exercise the affordance \(e.g. `GET /orders/2`\).
#### Real-world Examples
Some APIs using HAL:
* [Amazon AppStream REST API](http://docs.aws.amazon.com/appstream/latest/developerguide/appstream-api-rest.html)
* [FoxyCart](https://wiki.foxycart.com/v/2.0/start)
* [Clarify.io](http://docs.clarify.io/overview/)
* [University of Oxford / Mobile Oxford](http://api.m.ox.ac.uk/browser/#/)
## Working with HAL
Refer to the [extensive list of libraries that work with HAL](https://github.com/mikekelly/hal_specification/wiki/Libraries).
### Spring Framework
Spring framework supports HAL out of the box. More info can be found in [Spring Documentation](https://spring.io/guides/gs/rest-hateoas/) and [examples](https://github.com/spring-guides/gs-rest-hateoas).

View File

@@ -0,0 +1,16 @@
# Message Formats
## Response Message Format
All **response** messages **MUST** support an [`application/hal+json`](http://stateless.co/hal_specification.html) \(HAL\) format.
### Error Response Format
The [`application/problem+json`](https://tools.ietf.org/html/rfc7807) \(Problem Detail\) **MUST** be used to communicate details about an error.
## Request Message Format
**Request** messages with body **SHOULD** support a [`application/json`](http://www.json.org) \(JSON\) format. Where applicable, request message **SHOULD** also support the [`application/hal+json`](http://stateless.co/hal_specification.html) format.
**Request** messages **MAY** also support the [`application/x-www-form-urlencoded`](https://tools.ietf.org/html/rfc1866#section-8.2.1) \(URL Encoded\) format.

View File

@@ -0,0 +1,4 @@
# Protocol
This section outlines the protocol-level semantics and guidelines.

View File

@@ -0,0 +1,36 @@
# HTTP
Every API MUST support [HTTP/1.1](https://tools.ietf.org/html/rfc7230) and **MUST** adhere to its **semantic**.
## HTTP Protocol Quick Start
The understanding of HTTP starts with the understanding of [HTTP message](https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages) and its routing.
Once you are familiar with the **HTTP message structure** learn about the **HTTP request methods**, **HTTP response status codes** and **HTTP headers**.
Each HTTP request method, status code, and header have its semantics defined, and every API **MUST** strictly adhere to it.
Follow the [Robustness Principle](https://github.com/adidas-group/api-guidelines/tree/af88d15fd04ef18d6724fa65943901aab7328e7f/rest/protocol/core-principles/robustness.md). Use only the HTTP request methods, response codes and HTTP headers you understand, be liberal in accepting others.
## Know HTTP
The following documents are great overview of the HTTP protocol and related standards:
* [HTTP Headers](https://github.com/for-GET/know-your-http-well/blob/master/headers.md)
* [HTTP Request Methods](https://github.com/for-GET/know-your-http-well/blob/master/methods.md)
* [HTTP Response Status Codes](https://github.com/for-GET/know-your-http-well/blob/master/status-codes.md)
* [HTTP Link Relations](https://github.com/for-GET/know-your-http-well/blob/master/relations.md)
Alternatively, you can download HTTP cheat sheets at [HTTP posters](https://github.com/bigcompany/know-your-http).
## RFCs
The HTTP protocol semantics is defined in the following RFCs:
> 1. [RFC 7230, HTTP/1.1: Message Syntax and Routing](https://tools.ietf.org/html/rfc7230)
> 2. [RFC 7231, HTTP/1.1: Semantics and Content](https://tools.ietf.org/html/rfc7231)
> 3. [RFC 7232, HTTP/1.1: Conditional Requests](https://tools.ietf.org/html/rfc7232)
> 4. [RFC 7233, HTTP/1.1: Range Requests](https://tools.ietf.org/html/rfc7233)
> 5. [RFC 7234, HTTP/1.1: Caching](https://tools.ietf.org/html/rfc7234)
> 6. [RFC 7235, HTTP/1.1: Authentication](https://tools.ietf.org/html/rfc7234)

View File

@@ -0,0 +1,49 @@
# Separate Concerns
Every API using HTTP/S API **MUST** precisely follow the concern separation of an HTTP message:
1. A _resource identifier_URI **MUST** be used to indicate **identity** only
2. _HTTP request method_ **MUST** be used to communicate the **action semantics** \(intent and safety\)
3. _HTTP response status_ code **MUST** be used to communicate the **information about the result** of the attempt to understand and satisfy the request
4. _HTTP message body_ **MUST** be used to transfer the **message content**
5. _HTTP message headers_ **MUST** be used to transfer the **metadata** about the message and its content
6. _URI query parameter_ **SHOULD NOT** be used to transfer metadata
## Example 1
The rule
> A resource identifierURI **MUST** be used to indicate identity only
implies there **MUST NOT** be any information about the representation media type, version of the resource or anything else in the URI.
For example, URIs `/greeting.json` or `/v2.1.3/greeting` are **illegal** as they are not used for identification of a resource only but they convey the information about representation format or version. URIs are not meant to carry any other information but the identifier of the resource.
## Example 2
The rule
> HTTP message body MUST be used to transfer the message content
Implies an HTTP GET request **MUST NOT** use HTTP message body to identify the resource. For example a request:
```text
GET /greeting HTTP/1.1
Content-Type: application/json
...
{
"filter": "string"
"depth": 3
}
```
is **not acceptable** \(ignoring the fact that HTTP GET method shouldn't have the body\). To express identity use URI and query parameters instead e.g. `/greeting?filter=string&depth=3`.
> _Keep things simple while designing by separating the concerns between the different parts of the request and response cycle. Keeping simple rules here allows for greater focus on larger and harder problems._
>
> _Requests and responses will be made to address a particular resource or collection. Use the path to indicate identity, the body to transfer the contents and headers to communicate metadata. Query params may be used as a means to pass header information also in edge cases, but headers are preferred as they are more flexible and can convey more diverse information._
>
> __ [_Heroku HTTP API Design Guide_](https://geemus.gitbooks.io/http-api-design/content/en/foundations/separate-concerns.html)

View File

@@ -0,0 +1,6 @@
# TLS
Every API **MUST** require secure connections with **TLS 1.2**. That is, an API using the HTTP protocol **MUST** use **HTTPS**.
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.

View File

@@ -0,0 +1,44 @@
# Request Methods
Every API **MUST** use appropriate [HTTP request methods](https://github.com/for-GET/know-your-http-well/blob/master/methods.md) for every operation.
Every API designer, implementer and consumer **MUST** understand the semantic of the HTTP METHOD she is using.
At a minimum everyone **MUST** be familiar with the semantics of ["Common" HTTP Request Methods](https://github.com/for-GET/know-your-http-well/blob/master/methods.md#common): **DELETE**, **GET**, **HEAD**, **PUT**, **POST** and the [**PATCH** HTTP Request Method](https://tools.ietf.org/html/rfc5789#section-2). In addition, everyone **MUST** be aware which methods are **Safe**, **Idempotent** and **Cacheable**.
## Safe Methods
As per HTTP specification, the **GET** and **HEAD** methods should be used only for retrieval of resource representations and they do not update/delete the resource on the server. Both methods are said to be considered “safe“. This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested and they can update/delete the resource on the server and so should be used carefully.
## Idempotent Methods
The term idempotent is used more comprehensively to describe an operation that will produce the same results if executed once or multiple times. This is a beneficial property in many situations, as it means that a transaction can be repeated or retried as often as necessary without causing unintended effects. With non-idempotent operations, the algorithm may have to keep track of whether the operation was already performed or not. In HTTP specification, The methods **GET**, **HEAD**, **PUT** and **DELETE** are declared idempotent methods. Other methods OPTIONS and TRACE **SHOULD NOT** have side effects, so both are also inherently idempotent.
## Cacheable Methods
Request methods are considered "cacheable" if it is possible and useful to answer a current client request with a stored response from a prior request. **GET** and **HEAD** are defined to be cacheable.
### Example 1
> GET /user/new Description: Creates new user
Using GET for unsafe non-idempotent operations is **not acceptable**.
### Example 2
> POST /status Description: Updates the status of a user approval request \(to “Approved” or “Rejected”\)
Using the POST method for a status update is **not acceptable** \(use PATCH\).
### Example 3
> PUT /user Description: Creates a new user
Using the PUT method for creating a new resource is **not acceptable** \(use POST\).
### Example 4
> PUT: /user Description: Updates some user details
Using the PUT method for a partial update is **not acceptable** \(use PATCH\).

View File

@@ -0,0 +1,48 @@
# Status Codes
Every API **MUST** use the appropriate [HTTP Status Codes](https://github.com/for-GET/know-your-http-well/blob/master/status-codes.md) to communicate the result of a request operation.
Every API designer, implementer and consumer **MUST** understand the semantic of the HTTP Status Code she is using.
At a minimum everyone **MUST** be familiar with the semantics of ["Common" HTTP Status Codes](https://github.com/for-GET/know-your-http-well/blob/master/status-codes.md#common).
## Example
## Use Codes 4xx or 5xx to Communicate Errors
A request:
```text
GET /orders/1234 HTTP/1.1
...
```
resulting in the **200 OK** response, when the requested resource \(as identified by request URI\) couldn't be found:
```text
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"code": "NOT_FOUND_ERR_CODE"
"message" "Order 1234 wasn't found"
}
```
is **not acceptable**.
Instead the
```text
HTTP/1.1 404 Not Found
...
```
should be returned.
## Recommended Reading
* [How to Think About HTTP Status Codes](https://www.mnot.net/blog/2017/05/11/status_codes)