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,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="353px" height="133px" viewBox="0 0 353 133" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 45.1 (43504) - http://www.bohemiancoding.com/sketch -->
<title>Slice</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="logo2" transform="translate(26.000000, 30.000000)" fill="#333333">
<path d="M26.3594544,69.6770949 C11.8551182,69.6770949 -5.68434189e-14,57.7657907 -5.68434189e-14,43.2768619 C-5.68434189e-14,28.4352177 11.8551182,16.8766288 26.3594544,16.8766288 C31.9914403,16.8766288 37.3224566,18.3689279 41.7803226,21.3535488 L41.7803226,17.4735595 L54.1967554,17.4735595 L54.1967554,68.4561093 L41.7803226,68.4561093 L41.7803226,65.2001749 C37.3224566,67.8592079 32.3087213,69.6770949 26.3594544,69.6770949 Z M12.1723698,43.2768619 C12.1723698,50.9554614 18.9757842,57.7657907 26.6767061,57.7657907 C34.9606594,57.7657907 41.7803226,50.9554614 41.7803226,43.2768619 C41.7803226,35.2726712 34.9606594,28.4352177 26.6767061,28.4352177 C18.9757842,28.4352177 12.1723698,35.2726712 12.1723698,43.2768619 Z M85.0059381,69.6770949 C70.4880488,69.6770949 58.350926,57.7657907 58.350926,43.2768619 C58.350926,28.4352177 70.4880488,16.8766288 85.0059381,16.8766288 C90.627094,16.8766288 95.6842432,18.3689279 100.120417,21.3535488 L100.120417,9.76744185e-06 L112.851377,9.76744185e-06 L112.851377,68.4561093 L100.120417,68.4561093 L100.120417,65.2001749 C95.6842432,67.8592079 90.627094,69.6770949 85.0059381,69.6770949 Z M70.4880488,43.2768619 C70.4880488,50.9554614 77.3050184,57.7657907 85.6024982,57.7657907 C93.2898931,57.7657907 100.120417,50.9554614 100.120417,43.2768619 C100.120417,35.2726712 93.2898931,28.4352177 85.6024982,28.4352177 C77.3050184,28.4352177 70.4880488,35.2726712 70.4880488,43.2768619 Z M131.490914,68.4561093 L119.052787,68.4561093 L119.052787,17.4735595 L131.490914,17.4735595 L131.490914,68.4561093 Z M131.490914,12.7524567 L119.052787,12.7524567 L119.052787,9.76744185e-06 L131.490914,9.76744185e-06 L131.490914,12.7524567 Z M178.317524,9.76744185e-06 L190.736649,9.76744185e-06 L190.736649,68.4561093 L178.317524,68.4561093 L178.317524,65.2001749 C174.168797,67.8592079 168.826923,69.6770949 163.186796,69.6770949 C148.652632,69.6770949 136.840897,57.7657907 136.840897,43.2768619 C136.840897,28.4352177 148.652632,16.8766288 163.186796,16.8766288 C168.826923,16.8766288 173.843382,18.3689279 178.317524,21.3535488 L178.317524,9.76744185e-06 Z M148.978018,43.2768619 C148.978018,50.9554614 155.784127,57.7657907 163.485078,57.7657907 C171.484308,57.7657907 178.317524,50.9554614 178.317524,43.2768619 C178.317524,35.2726712 171.484308,28.4352177 163.485078,28.4352177 C155.784127,28.4352177 148.978018,35.2726712 148.978018,43.2768619 Z M221.540447,69.6770949 C207.006251,69.6770949 194.885405,57.7657907 194.885405,43.2768619 C194.885405,28.4352177 207.006251,16.8766288 221.540447,16.8766288 C227.18057,16.8766288 232.197029,18.3689279 236.345785,21.3535488 L236.345785,17.4735595 L249.063189,17.4735595 L249.063189,68.4561093 L236.345785,68.4561093 L236.345785,65.2001749 C232.197029,67.8592079 227.18057,69.6770949 221.540447,69.6770949 Z M207.304529,43.2768619 C207.304529,50.9554614 214.137778,57.7657907 222.136978,57.7657907 C229.810819,57.7657907 236.345785,50.9554614 236.345785,43.2768619 C236.345785,35.2726712 229.810819,28.4352177 222.136978,28.4352177 C214.137778,28.4352177 207.304529,35.2726712 207.304529,43.2768619 Z M276.938431,69.6770949 C289.384666,69.6770949 299.770106,64.57612 299.770106,52.1221693 C299.770106,45.013373 294.753648,40.2922409 286.754421,38.2301679 C278.429802,36.1409414 267.800326,36.4665326 267.800326,31.1213749 C268.36978,27.5669767 271.6508,26.6715823 276.667259,26.6715823 C284.368207,26.6715823 284.666489,30.8229079 284.964768,33.4819116 L297.682175,33.4819116 C296.787335,23.6869614 288.815242,16.8766288 276.097835,16.8766288 C262.75676,16.8766288 255.028705,24.0125493 255.028705,33.2106014 C255.028705,38.5286349 257.686057,43.2768619 262.160203,45.6374279 C265.414116,47.1297237 269.861151,48.2964316 275.175888,49.191826 C280.816015,49.7616 285.886718,50.3585307 286.15786,54.23852 C286.15786,56.9246772 283.473397,60.1534842 277.562099,60.1534842 C268.966311,60.1534842 267.203795,55.4052247 267.203795,52.1221693 L253.86272,52.1221693 C254.161002,62.5140209 262.75676,69.6770949 276.938431,69.6770949 L276.938431,69.6770949 Z" id="path34" fill-rule="nonzero"></path>
<path d="M291.391243,1.19387116 C294.645185,1.19387116 297.356785,3.88002837 297.356785,7.40726977 C297.356785,10.6360767 294.645185,13.322234 291.391243,13.322234 C288.164466,13.322234 285.452867,10.6360767 285.452867,7.40726977 C285.452867,3.88002837 288.164466,1.19387116 291.391243,1.19387116 Z M291.391243,2.00786047 C288.462716,2.00786047 286.293459,4.42267814 286.293459,7.40726977 C286.293459,10.093427 288.462716,12.5082414 291.391243,12.5082414 C294.129979,12.5082414 296.516193,10.093427 296.516193,7.40726977 C296.516193,4.42267814 294.129979,2.00786047 291.391243,2.00786047 Z M292.747041,7.40726977 C293.045323,7.40726977 293.831701,7.6786093 293.831701,8.73678465 L293.831701,10.6360767 L292.747041,10.6360767 L292.747041,9.82208744 C292.747041,8.46544512 292.475899,7.92279535 291.662414,7.92279535 L290.333723,7.92279535 L290.333723,10.6360767 L289.249093,10.6360767 L289.249093,3.88002837 L291.391243,3.88002837 C292.747041,3.88002837 293.831701,4.72114186 293.831701,5.77931721 C293.831701,6.59330977 293.316495,7.40726977 292.747041,7.40726977 Z M290.333723,4.96532791 L290.333723,6.86462 L291.391243,6.86462 C291.960693,6.86462 292.747041,6.59330977 292.747041,6.05062744 C292.747041,5.50797767 292.231868,4.96532791 291.662414,4.96532791 L290.333723,4.96532791 L290.333723,4.96532791 Z" id="path36"></path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -1,33 +1,35 @@
# Introduction
![adidas logo](https://adidas-group.gitbooks.io/api-guidelines/content/assets/adidas-logo.svg)
# adidas API Guidelines
## adidas API Guidelines
_Guidelines for API design at adidas_ \([Read online at GitBook](https://adidas-group.gitbooks.io/api-guidelines/content/)\)
## Motivation
### Motivation
The goal of this document is to facilitate the work and minimize the effort of all API users while protecting their investment and encouraging API adoption.
The guidelines lay down the foundation for collaboration, stability, and extensibility.
## Guidelines
### Guidelines
The API Guidelines are split into two main parts:
* [General Guidelines](/general-guidelines/README.md)
* [General Guidelines](general-guidelines/general-guidelines.md)
* API type-specific Guidelines
* [REST APIs Guidelines](/rest/README.md)
* [Kafka Guidelines](/kafka/README.md)
* [REST APIs Guidelines](rest-api-guidelines/rest.md)
* [Kafka Guidelines](kafka-guidelines/kafka.md)
The general guidelines section discusses the core principles relevant to any kind of API. The API type-specific section further defines the guidelines specific to a given architectural style or API technique \(such as REST, Kafka or GraphQL API\).
## How to read the Guidelines
### How to read the Guidelines
These Guidelines are available for online reading at [GitBook](https://apidesigner.gitbooks.io/adidas-api-guidelines/content/) its source can be found on [GitHub](https://github.com/adidas-group/api-guidelines).
The CAPITALIZED words throughout these guidelines have a special meaning:
> ```
> ```text
> The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
> "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in
> this document are to be interpreted as described in RFC2119.
@@ -35,7 +37,7 @@ The CAPITALIZED words throughout these guidelines have a special meaning:
Refer to [RFC2119](https://www.ietf.org/rfc/rfc2119) for details.
## Questions & Comments
### Questions & Comments
_Please contact _[_Zdenek.Nemec@externals.adidas-group.com_](mailto:Zdenek.Nemec@externals.adidas-group.com)_ in the case of questions._
_Please contact_ [_Zdenek.Nemec@externals.adidas-group.com_](mailto:Zdenek.Nemec@externals.adidas-group.com) _in the case of questions._

View File

@@ -1,12 +1,14 @@
# Summary
# Table of contents
* [Introduction](README.md)
## Introduction
* [adidas API Guidelines](README.md)
* [adidas API Guidelines](introduction/readme.md)
## General Guidelines
* [Introduction](general-guidelines/README.md)
* [Introduction](general-guidelines/general-guidelines.md)
* [API First](general-guidelines/api-first.md)
* [Contract](general-guidelines/contract.md)
* [Robustness](general-guidelines/robustness.md)
@@ -18,53 +20,53 @@
## REST API Guidelines
* [Introduction](rest/README.md)
* [Core Principles](rest/core-principles/README.md)
* [OpenAPI Specification](rest/core-principles/openapi-specification.md)
* [API Design Platform](rest/core-principles/apiary.md)
* [Design Maturity](rest/core-principles/design-maturity.md)
* [Testing](rest/core-principles/testing.md)
* [Functionality](core-principles/functional.md)
* [Protocol](rest/protocol/README.md)
* [HTTP](rest/protocol/http.md)
* [TLS](rest/protocol/tls.md)
* [Separate Concerns](rest/protocol/separate-concerns.md)
* [Request Methods](rest/protocol/use-appropriate-methods.md)
* [Status Codes](rest/protocol/use-appropriate-status-codes.md)
* [Message](rest/message/README.md)
* [Message Formats](rest/message/message-formats.md)
* [Content Negotiation](rest/message/content-negotiation.md)
* [HAL](rest/message/hal.md)
* [Problem Detail](rest/message/error-reporting.md)
* [Foreign Key Relations](rest/message/foreign-key-relations.md)
* [Application](rest/application/README.md)
* [Corporate Data Model](rest/application/harmonize-data.md)
* [Common Data Types](rest/application/common-data-types.md)
* [Quality](rest/core-principles/quality.md)
* [Execution](rest/execution/README.md)
* [Pagination](rest/execution/pagination.md)
* [Asynchronous Tasks](rest/execution/asynchronous-tasks.md)
* [Batch Operations](rest/execution/batch-operations.md)
* [Search Requests](rest/execution/search-requests.md)
* [Query Requests with Large Inputs](rest/execution/query-requests-with-large-inputs.md)
* [Choosing Fields and Embedded Resources](rest/execution/choosing-fields-and-embedded-resoruces.md)
* [Localization](rest/execution/localization.md)
* [Rate Limiting](rest/execution/rate-limiting.md)
* [Caching](rest/execution/caching.md)
* [Evolution](rest/evolution/README.md)
* [Naming Conventions](rest/evolution/naming-conventions.md)
* [Reserved Identifiers](rest/evolution/reserved-identifiers.md)
* [URI Structure](rest/evolution/uri-structure.md)
* [Changes and Versioning](rest/evolution/versioning.md)
* [Testing Enviroments](rest/execution/testing-enviroments.md)
* [Guides](rest/guides/README.md)
* [API Testing CI Environment](rest/guides/api-testing-ci-environment.md)
* [Complete API Development](rest/guides/complete-api-development.md)
* [API Clients](rest/clients/README.md)
* [Loose Coupling](rest/clients/loose-coupling.md)
* [Further References](rest/miscellaneous.md)
* [Introduction](rest-api-guidelines/rest.md)
* [Core Principles](rest-api-guidelines/core-principles/README.md)
* [OpenAPI Specification](rest-api-guidelines/core-principles/openapi-specification.md)
* [API Design Platform](rest-api-guidelines/core-principles/apiary.md)
* [Design Maturity](rest-api-guidelines/core-principles/design-maturity.md)
* [Testing](rest-api-guidelines/core-principles/testing.md)
* [Functionality](rest-api-guidelines/functionality/README.md)
* [Protocol](rest-api-guidelines/functionality/protocol/README.md)
* [HTTP](rest-api-guidelines/functionality/protocol/http.md)
* [TLS](rest-api-guidelines/functionality/protocol/tls.md)
* [Separate Concerns](rest-api-guidelines/functionality/protocol/separate-concerns.md)
* [Request Methods](rest-api-guidelines/functionality/protocol/use-appropriate-methods.md)
* [Status Codes](rest-api-guidelines/functionality/protocol/use-appropriate-status-codes.md)
* [Message](rest-api-guidelines/functionality/message/README.md)
* [Message Formats](rest-api-guidelines/functionality/message/message-formats.md)
* [Content Negotiation](rest-api-guidelines/functionality/message/content-negotiation.md)
* [HAL](rest-api-guidelines/functionality/message/hal.md)
* [Problem Detail](rest-api-guidelines/functionality/message/error-reporting.md)
* [Foreign Key Relations](rest-api-guidelines/functionality/message/foreign-key-relations.md)
* [Application](rest-api-guidelines/functionality/application/README.md)
* [Corporate Data Model](rest-api-guidelines/functionality/application/harmonize-data.md)
* [Common Data Types](rest-api-guidelines/functionality/application/common-data-types.md)
* [Quality](rest-api-guidelines/quality/README.md)
* [Execution](rest-api-guidelines/quality/execution/README.md)
* [Pagination](rest-api-guidelines/quality/execution/pagination.md)
* [Asynchronous Tasks](rest-api-guidelines/quality/execution/asynchronous-tasks.md)
* [Batch Operations](rest-api-guidelines/quality/execution/batch-operations.md)
* [Search Requests](rest-api-guidelines/quality/execution/search-requests.md)
* [Query Requests with Large Inputs](rest-api-guidelines/quality/execution/query-requests-with-large-inputs.md)
* [Choosing Fields and Embedded Resources](rest-api-guidelines/quality/execution/choosing-fields-and-embedded-resoruces.md)
* [Localization](rest-api-guidelines/quality/execution/localization.md)
* [Rate Limiting](rest-api-guidelines/quality/execution/rate-limiting.md)
* [Caching](rest-api-guidelines/quality/execution/caching.md)
* [Evolution](rest-api-guidelines/quality/evolution/README.md)
* [Naming Conventions](rest-api-guidelines/quality/evolution/naming-conventions.md)
* [Reserved Identifiers](rest-api-guidelines/quality/evolution/reserved-identifiers.md)
* [URI Structure](rest-api-guidelines/quality/evolution/uri-structure.md)
* [Changes and Versioning](rest-api-guidelines/quality/evolution/versioning.md)
* [Testing Enviroments](rest-api-guidelines/quality/evolution/testing-enviroments.md)
* [Guides](rest-api-guidelines/guides/README.md)
* [API Testing CI Environment](rest-api-guidelines/guides/api-testing-ci-environment.md)
* [Complete API Development](rest-api-guidelines/guides/complete-api-development.md)
* [API Clients](rest-api-guidelines/clients/README.md)
* [Loose Coupling](rest-api-guidelines/clients/loose-coupling.md)
* [Further References](rest-api-guidelines/miscellaneous.md)
## Kafka Guidelines
* [Introduction](kafka/README.md)
* [Introduction](kafka-guidelines/kafka.md)

View File

@@ -4,7 +4,7 @@ Everyone **MUST** follow the **API First** principle.
The API first principle is an extension of contract-first principle. Therefore, a development of an API **MUST** always start with API design without any upfront coding activities.
**API design **\(e.g., description, schema\)** is the master of truth, not the API implementation.**
**API design** \(e.g., description, schema\) **is the master of truth, not the API implementation.**
API implementation **MUST** always be compliant to particular API design which represents the [contract](./contract.md) between API, and it's consumer.
API implementation **MUST** always be compliant to particular API design which represents the [contract](contract.md) between API, and it's consumer.

View File

@@ -1,6 +1,6 @@
# ![](/assets/adidas-logo.svg)
# Introduction
# adidas General API Guidelines
## adidas General API Guidelines
Set of general rules and recommendations that have to be followed along the entire API lifecycle of any API regardless of its type.

View File

@@ -1,9 +1,11 @@
# JSON Format Conventions
# JSON
Any JSON-based message **MUST** conform to the following rules:
1. All JSON field names **MUST** follow the [Naming Conventions](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/naming-conventions.html) (`camelCase`, American English, etc.)
1. Field names **MUST** be ASCII alpha num characters, underscore (`_`) or dollar sign (`$`)
1. Boolean fields **MUST NOT** be of `null` value
1. Fields with `null` value **SHOULD** be omitted
1. Empty arrays and objects **SHOULD NOT ** be `null` (use `[]` or `{}` instead)
1. Array field names **SHOULD** be plural (e.g. `"orders": []`)
1. All JSON field names **MUST** follow the [Naming Conventions ](../rest-api-guidelines/quality/evolution/naming-conventions.md)\(`camelCase`, American English, etc.\)
2. Field names **MUST** be ASCII alpha num characters, underscore \(`_`\) or dollar sign \(`$`\)
3. Boolean fields **MUST NOT** be of `null` value
4. Fields with `null` value **SHOULD** be omitted
5. Empty arrays and objects **SHOULD NOT** be `null` \(use `[]` or `{}` instead\)
6. Array field names **SHOULD** be plural \(e.g. `"orders": []`\)

View File

@@ -1,2 +1,4 @@
# Minimal API Surface
Every API design **MUST** aim for a minimal API surface without sacrificing on product requirements. API design **SHOULD NOT** include unnecessary resources, relations, actions or data. API design **SHOULD NOT** add functionality until deemed necessary ([YAGNI principle](https://martinfowler.com/bliki/Yagni.html)).
Every API design **MUST** aim for a minimal API surface without sacrificing on product requirements. API design **SHOULD NOT** include unnecessary resources, relations, actions or data. API design **SHOULD NOT** add functionality until deemed necessary \([YAGNI principle](https://martinfowler.com/bliki/Yagni.html)\).

View File

@@ -1,8 +1,10 @@
# Robustness
# Robustness
Every API implementation and API consumer **MUST** follow Postel's law:
> _Be conservative in what you send, be liberal in what you accept._
>
> _ [John Postel](https://en.wikipedia.org/wiki/Robustness_principle)_
> __ [_John Postel_](https://en.wikipedia.org/wiki/Robustness_principle)
That is, send the necessary minimum and be tolerant as possible while consuming another service \([tolerant reader](https://martinfowler.com/bliki/TolerantReader.html)\).
That is, send the necessary minimum and be tolerant as possible while consuming another service ([tolerant reader](https://martinfowler.com/bliki/TolerantReader.html)).

View File

@@ -1,15 +1,16 @@
# Rules for Extending
Any modification to an existing API **MUST** avoid breaking changes and **MUST** maintain backward compatibility.
In particular, any change to an API **MUST** follow the following **Rules for Extending**:
1. **You MUST NOT take anything away** (related: [Minimal Surface Principle](core-principles/minimal-api-surface.md)
, [Robustness Principle](core-principles/robustness.md))
1. **You MUST NOT take anything away** \(related: [Minimal Surface Principle](minimal-api-surface.md)
, [Robustness Principle](robustness.md)\)
2. **You MUST NOT change processing rules**
3. **You MUST NOT make optional things required**
4. **Anything you add MUST be optional** (related [Robustness Principle](core-principles/robustness.md))
> NOTE: These rules cover also renaming and change to identifiers (URIs). Names and identifiers should be stable over the time including their semantics.
4. **Anything you add MUST be optional** \(related [Robustness Principle](robustness.md)\)
> NOTE: These rules cover also renaming and change to identifiers \(URIs\). Names and identifiers should be stable over the time including their semantics.

View File

@@ -1,19 +1,25 @@
# API Authentication
# Security
Every registered API MUST be assigned a unique Client ID and a Client Secret as a part of an HTTP header. The Client Secret MUST NOT be shared. DO NOT solely rely on a Client ID for authentication.
## Access Control
Not every user has a right to every web service. This is vital, as you don't want administrative web services to be misused. The API key SHOULD be sent along as a cookie, body parameter, or HTTP message header to ensure that privileged collections or actions are properly protected from unauthorized use. Every API MUST BE authenticated before it can be used.
## Masking HTTP Headers
Server versioning information or any other sensitive information from the HTTP headers SHOULD BE removed/masked according to industry best practices. This prevents any form of targeted attacks since the vulnerabilities are mostly specific to the vendors.
## Session Management
RESTful web services SHOULD use session-based authentication, either by establishing a session token via a POST or by using an API key (Client ID and a Client Secret) as a POST body argument or as a cookie. Usernames, passwords, session tokens, API keys, and sensitive information MUST NOT appear in the URL, as this can be captured in web server logs, which makes them intrinsically valuable.
RESTful web services SHOULD use session-based authentication, either by establishing a session token via a POST or by using an API key \(Client ID and a Client Secret\) as a POST body argument or as a cookie. Usernames, passwords, session tokens, API keys, and sensitive information MUST NOT appear in the URL, as this can be captured in web server logs, which makes them intrinsically valuable.
## Protect HTTP Methods
RESTful API often use GET (read), POST (create), PUT (replace/update) and DELETE (to delete a record). Not all of these are valid choices for every single resource collection, user, or action. Make sure the incoming HTTP method is valid for the session token/API key and associated resource collection, action, and record.
RESTful API often use GET \(read\), POST \(create\), PUT \(replace/update\) and DELETE \(to delete a record\). Not all of these are valid choices for every single resource collection, user, or action. Make sure the incoming HTTP method is valid for the session token/API key and associated resource collection, action, and record.
## HTTP Status Codes
While designing a REST API, DON'T just use 200 for success or 404 for error. Every error message needs to be customized as NOT to reveal any unnecessary information. Here are some guidelines to consider for each REST API status return code. Proper error handle may help to validate the incoming requests and better identify the potential security risks.
* 200 OK - Response to a successful REST API action.
@@ -25,25 +31,25 @@ While designing a REST API, DON'T just use 200 for success or 404 for error. Eve
* 429 Too Many Requests - The error is used when there may be DOS attack detected or the request is rejected due to rate limiting
## Input Validation
Everything you know about [input validation](https://www.owasp.org/index.php/Data_Validation) applies to RESTful web services, but add 10% because automated tools can easily fuzz your interfaces for hours on end at high velocity. Help the user input high-quality data into your web services, such as ensuring a Zip code makes sense for the supplied address, or the date makes sense. If not, reject that input. Also, make sure that the output encoding is robust for your application. Some other specific forms of input validations need to be implemented:
* Secure parsing: Use a secure parser for parsing the incoming messages. If you are using XML, make sure to use a parser that is NOT VULNERABLE to XXE and similar attacks.
* Strong typing: It's difficult to perform most attacks if the only allowed values are true or false, or a number, or one of a small number of acceptable values. Strongly type incoming data as quickly as possible.
* Validate incoming content-types: When POSTing or PUTting new data, the client will specify the Content-Type (e.g. application/xml or application/json) of the incoming data. The server SHOULD NEVER assume the Content-Type; it SHOULD ALWAYS check that the Content-Type header and the content are the same types. A lack of Content-Type header or an unexpected Content-Type header SHOULD result in the server rejecting the content with a 406 Not Acceptable response.
* Validate response types: It is common for REST services to allow multiple response types (e.g. application/xml or application/json, and the client specifies the preferred order of response types by the Accept header in the request. DO NOT simply copy the Accept header to the Content-type header of the response. Reject the request (ideally with a 406 Not Acceptable response) if the Accept header does not specifically contain one of the allowable types. Because there are many MIME types for the typical response types, it's important to document for clients specifically which MIME types should be used.
* Validate incoming content-types: When POSTing or PUTting new data, the client will specify the Content-Type \(e.g. application/xml or application/json\) of the incoming data. The server SHOULD NEVER assume the Content-Type; it SHOULD ALWAYS check that the Content-Type header and the content are the same types. A lack of Content-Type header or an unexpected Content-Type header SHOULD result in the server rejecting the content with a 406 Not Acceptable response.
* Validate response types: It is common for REST services to allow multiple response types \(e.g. application/xml or application/json, and the client specifies the preferred order of response types by the Accept header in the request. DO NOT simply copy the Accept header to the Content-type header of the response. Reject the request \(ideally with a 406 Not Acceptable response\) if the Accept header does not specifically contain one of the allowable types. Because there are many MIME types for the typical response types, it's important to document for clients specifically which MIME types should be used.
* XML input validation: XML-based services MUST ensure that they are protected against common XML-based attacks by using secure XML-parsing. This typically means protecting against XML External Entity attacks, XML-signature wrapping etc.
## Escape Content
This means removing any executable code that would cause the browser to do something you dont want it to. Typically this means removing `// &lt;![CDATA[` tags and HTML attributes that cause JavaScript to be evaluated. If you use standard data formats like JSON, you can use standard libraries which have been thoroughly checked by many professionals. However, DO NOT TRY TO DO THIS YOURSELF. Use a known library or the auto-escaping features of your favorite template library. This needs to be done in the browser and on your server if you allow users to submit data that is saved into a database.
## Restrict Testing Environment
THUMB Rule. No production data or any form of sensitive data to be used while testing the APIs in the testing environment.
## Storing Tokens at Client Side
There are two ways to save authentication information in the browser:
* Cookies
@@ -51,41 +57,42 @@ There are two ways to save authentication information in the browser:
In each case, you have to trust that browsers are implemented correctly and that Website A can't somehow access the authentication information for Website B. In that sense, both storage mechanisms are equally secure. Problems can arise regarding how you use them though.
- If you use cookies: The browser will automatically send the authentication information with every request to the API. This can be convenient so long as you know it's happening. Prevention against CSRF is a must while using this technique. It is also strongly recommended to use cookies with HTTPOnly and Secure flags set. This will allow the browser to send along the token for authentication purposes, but wont expose it to the JavaScript environment.
- If you use HTML5 Web Storage: You have to write JavaScript that manages exactly when and what authentication information is sent.
* If you use cookies: The browser will automatically send the authentication information with every request to the API. This can be convenient so long as you know it's happening. Prevention against CSRF is a must while using this technique. It is also strongly recommended to use cookies with HTTPOnly and Secure flags set. This will allow the browser to send along the token for authentication purposes, but wont expose it to the JavaScript environment.
* If you use HTML5 Web Storage: You have to write JavaScript that manages exactly when and what authentication information is sent.
## Protect against Cross-Site Request Forgery
For resources exposed by RESTful web services, it's important to make sure any PUT, POST, and DELETE request is protected from Cross Site Request Forgery. Typically, one would use a token-based approach. See [Cross-Site Request Forgery Prevention Cheat Sheet](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet
) for more information on how to implement CSRF-protection.
CSRF is easily achieved even using random tokens if any XSS exists within your application, so PLEASE MAKE SURE you understand [how to prevent XSS][preventxss].
For resources exposed by RESTful web services, it's important to make sure any PUT, POST, and DELETE request is protected from Cross Site Request Forgery. Typically, one would use a token-based approach. See [Cross-Site Request Forgery Prevention Cheat Sheet](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29_Prevention_Cheat_Sheet) for more information on how to implement CSRF-protection.
[preventxss]: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
CSRF is easily achieved even using random tokens if any XSS exists within your application, so PLEASE MAKE SURE you understand [how to prevent XSS](https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet).
## Insecure direct object references
A URL or even a POSTed form should NEVER contain an access control "key" or similar that provides automatic verification. A contextual data check needs to be done, server side, with each request.
## Enable CORS for all APIs
When your API's resources receive requests from a domain other than the API's domain, you MUST enable cross-origin resource sharing (CORS) for selected methods on the resource. This amounts to having your API respond to the OPTIONS preflight request with at least the following CORS-required response headers:
When your API's resources receive requests from a domain other than the API's domain, you MUST enable cross-origin resource sharing \(CORS\) for selected methods on the resource. This amounts to having your API respond to the OPTIONS preflight request with at least the following CORS-required response headers:
* Access-Control-Allow-Methods
* Access-Control-Allow-Headers
* Access-Control-Allow-Origin
## Data in transit
Unless the public information is entirely read-only, the use of TLS v1.2 should be MANDATED, especially when credentials, updates, deletions, and any value transactions are performed. The overhead of TLS is negligible on modern hardware, with a minor latency increase that is more than compensated by safety for the end user.
## Message Integrity
In addition to HTTPS/TLS, JSON Web Token (JWT) is an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. JWT can not only be used to ensure the message integrity but also authentication of both message sender/receiver. The JWT includes the digital signature hash value of the message body to ensure the message integrity during the transmission.
In addition to HTTPS/TLS, JSON Web Token \(JWT\) is an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. JWT can not only be used to ensure the message integrity but also authentication of both message sender/receiver. The JWT includes the digital signature hash value of the message body to ensure the message integrity during the transmission.
## Weak SSL/TLS Ciphers Support:
The encryption ciphers supported by the server may allow an attacker to eavesdrop on the connection. Verify the following guidelines:
* When serving up content to your users, ONLY strong ciphers are enabled (128 bits and above).
* When serving up content to your users, ONLY strong ciphers are enabled \(128 bits and above\).
* When connecting to other remote systems ensure that your client DOES NOT connect using a weak cipher if the server supports it.
* Renegotiation MUST be properly configured (e.g. Insecure Renegotiation MUST be disabled, due to MiTM attacks and Client-initiated Renegotiation MUST be disabled, due to Denial of Service vulnerability).
* Renegotiation MUST be properly configured \(e.g. Insecure Renegotiation MUST be disabled, due to MiTM attacks and Client-initiated Renegotiation MUST be disabled, due to Denial of Service vulnerability\).
* MD5 MUST NOT be used, due to known collision attacks.
* RC4 MUST NOT be used, due to cryptoanalytical attacks
* Server SHOULD be protected from BEAST Attack
@@ -93,23 +100,28 @@ The encryption ciphers supported by the server may allow an attacker to eavesdro
* Server SHOULD support Forward Secrecy
## Mixed Content
When serving up content to your users over SSL, its important that you DO NOT include content served over HTTP such as Images, JavaScript, Flash, or CSS. By mixing HTTP content with HTTPS content, you expose your users to man in the middle attacks and eliminate the security benefits that SSL/TLS provides.
## SSL Certificate Validity client and server
For the communication to be set up, a number of checks on the certificates MUST be passed:
* Checking if the Certificate Authority (CA) is a known one (meaning one considered trusted);
* Checking if the Certificate Authority \(CA\) is a known one \(meaning one considered trusted\);
* Checking that the certificate is currently valid;
* Checking that the name of the site and the name reported in the certificate match.
## Certificate Requirements
The following checklist NEEDS TO BE followed while using an SSL certificate:
* X.509 certificates key length MUST be strong (e.g. if RSA or DSA is used the key MUST be at least 1024 bits).
* X.509 certificates MUST be signed only with secure hashing algorithms (e.g. not signed using the MD5 hash, due to known collision attacks on this hash).
* Fully Qualified Domain Name (FQDN) certificates is a MANDATE. This is a certificate that has been issued with a name registered with an entity that manages a top-level domain (TLD). The differentiating characteristic about an FQDN is that it is unique. There is one controller and that controller determines who can have any name under that root.
* X.509 certificates key length MUST be strong \(e.g. if RSA or DSA is used the key MUST be at least 1024 bits\).
* X.509 certificates MUST be signed only with secure hashing algorithms \(e.g. not signed using the MD5 hash, due to known collision attacks on this hash\).
* Fully Qualified Domain Name \(FQDN\) certificates is a MANDATE. This is a certificate that has been issued with a name registered with an entity that manages a top-level domain \(TLD\). The differentiating characteristic about an FQDN is that it is unique. There is one controller and that controller determines who can have any name under that root.
* NO USAGE of Wildcard SSL Certificate.
* SHA-1 (or MD5) certificates SHOULD NOT BE used. The problem isn't the security of the server's real certificate; it's the client policy that allows the client to trust low-security certificates.
* SHA-1 \(or MD5\) certificates SHOULD NOT BE used. The problem isn't the security of the server's real certificate; it's the client policy that allows the client to trust low-security certificates.
## Penetration Testing
An exhaustive penetration testing needs to be performed against all the developed APIs exposed to the public internet and within adidas internal network. For detailed understanding of the process, please contact the adidas Global IT Security Team.

43
introduction/readme.md Normal file
View File

@@ -0,0 +1,43 @@
# adidas API Guidelines
![adidas logo](https://adidas-group.gitbooks.io/api-guidelines/content/assets/adidas-logo.svg)
## adidas API Guidelines
_Guidelines for API design at adidas_ \([Read online at GitBook](https://adidas-group.gitbooks.io/api-guidelines/content/)\)
### Motivation
The goal of this document is to facilitate the work and minimize the effort of all API users while protecting their investment and encouraging API adoption.
The guidelines lay down the foundation for collaboration, stability, and extensibility.
### Guidelines
The API Guidelines are split into two main parts:
* [General Guidelines](../general-guidelines/general-guidelines.md)
* API type-specific Guidelines
* [REST APIs Guidelines](../rest-api-guidelines/rest.md)
* [Kafka Guidelines](../kafka-guidelines/kafka.md)
The general guidelines section discusses the core principles relevant to any kind of API. The API type-specific section further defines the guidelines specific to a given architectural style or API technique \(such as REST, Kafka or GraphQL API\).
### How to read the Guidelines
These Guidelines are available for online reading at [GitBook](https://apidesigner.gitbooks.io/adidas-api-guidelines/content/) its source can be found on [GitHub](https://github.com/adidas-group/api-guidelines).
The CAPITALIZED words throughout these guidelines have a special meaning:
> ```text
> The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
> "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in
> this document are to be interpreted as described in RFC2119.
> ```
Refer to [RFC2119](https://www.ietf.org/rfc/rfc2119) for details.
### Questions & Comments
_Please contact_ [_Zdenek.Nemec@externals.adidas-group.com_](mailto:Zdenek.Nemec@externals.adidas-group.com) _in the case of questions._

View File

@@ -0,0 +1,6 @@
# Introduction
## ![](../.gitbook/assets/adidas-logo.svg)
## adidas Kafka Guidelines

View File

@@ -1,6 +0,0 @@
# ![](/assets/adidas-logo.svg)
# adidas Kafka Guidelines

View File

@@ -1,2 +1,4 @@
# API Consumers Clients
# API Clients
This section contains the recommended practices for API consumersclients.

View File

@@ -0,0 +1,6 @@
# Loose Coupling
In addition to the [robustness principle](https://github.com/adidas-group/api-guidelines/tree/af88d15fd04ef18d6724fa65943901aab7328e7f/rest/clients/core-principles/robustness.md), API consumers \(clients\) **MUST** **operate independently** on API implementation's internals. Similarly the API consumers **MUST NOT** **assume** or **rely on** any knowledge of the API service internal implementation.
Where available, the clients **SHOULD** utilize **hypermedia controls as the engine of the application state**, and rely on the **protocol, message and vocabulary semantics**.

View File

@@ -1,2 +1,4 @@
# Core Principles
This section outlines the foundation upon which the API Guidelines are built.
This section outlines the foundation upon which the API Guidelines are built.

View File

@@ -0,0 +1,12 @@
# API Design Platform
1. [Apiary](https://apiary.io/) is the primary platform supporting [API first approach](https://github.com/adidas-group/api-guidelines/tree/af88d15fd04ef18d6724fa65943901aab7328e7f/rest/core-principles/api-first.md). Apiary **MUST** be used during API Design.
2. Every API description **MUST** be stored in [Apiary](https://apiary.io/) under the ADIDAS GROUP team.
3. Apiary **MUST** be the **single source of truth** to learn about existing APIs within the organization.
> NOTE: Apiary supports API-first approach in multiple ways:
> a. Validates API description for correctness and automatically generates API documentation to drive the discussion between stakeholders. \(No more emails with API description flying between stakeholders\)
>
> NOTE: The synchronization between the version control system and adidas [API Description platform](apiary.md)
> should be automated using CI/CD framework.

View File

@@ -0,0 +1,18 @@
# Design Maturity
## API Design Maturity
> How to design an API
Every API design **MUST** be **resource-centric** \([Web API Design Maturity Model Level 2](http://amundsen.com/talks/2016-11-apistrat-wadm/2016-11-apistrat-wadm.pdf)\). That is an API design **MUST** revolve around Web-styled _resources_, _relations_ between the resources and the _actions_ the resources may afford.
An API design **MAY** be **affordance-centric** \([Web API Design Maturity Model Level 3](http://amundsen.com/talks/2016-11-apistrat-wadm/2016-11-apistrat-wadm.pdf)\).
## API Design Implementation Maturity
> How to implement the API design
Every API design implementation using the HTTP protocol **MUST** use the appropriate **HTTP Request Method** \([Richardson Maturity Model Level 2](https://martinfowler.com/articles/richardsonMaturityModel.html#level2)\) to implement an action afforded by a resource.
An API design implementation **SHOULD** include **hypermedia controls** \(HATEOAS\) \([Richardson Maturity Model Level 3](https://martinfowler.com/articles/richardsonMaturityModel.html#level3)\).

View File

@@ -1,7 +1,10 @@
# OpenAPI Specification
Every API **MUST** be described using an API description format. The API description format used MUST be the [OpenAPI Specification (formerly known as Swagger Specification) version 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md).
Every API description **MUST** be published in adidas [API design platform](./apiary.md) and it **SHOULD** be stored in version control system (Bitbucket, GitHub) in the same repository as the API implementation.
Every API **MUST** be described using an API description format. The API description format used MUST be the [OpenAPI Specification \(formerly known as Swagger Specification\) version 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md).
Every API description **MUST** be published in adidas [API design platform](apiary.md) and it **SHOULD** be stored in version control system \(Bitbucket, GitHub\) in the same repository as the API implementation.
## Language
The API description MUST be written in **American English**.

View File

@@ -0,0 +1,6 @@
# Testing
Every API description \(contract\) using HTTP\(S\) protocol **MUST** be tested against its API implementation. The tests **MUST** be executed using the [Dredd testing framework](https://github.com/apiaryio/dredd). The Dredd **MUST** [report the test results to Apiary](https://help.apiary.io/tools/automated-testing/testing-reporter/).
In addition to local runs, the tests **SHOULD** be an integral part the API implementation's CI/CD pipeline. The CI/CD pipeline **SHOULD** be configured to run the test whenever there is a change to either API description \(contract\) or its implementation.

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

@@ -1,37 +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).
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).
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`
* `createdAt`
* `updatedAt`
* `finishedAt`
#### Example
### Example
```json
```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

@@ -1,10 +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 Data Dictionary/Data Dictionary.htm) (internal link).
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

@@ -1,28 +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:
## 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:
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 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

@@ -1,13 +1,14 @@
# Problem Detail
The [`application/problem+json`](https://tools.ietf.org/html/rfc7807) (Problem Detail) **MUST** be used to communicate details about an error.
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.
At the minimum, any Problem Detail response **MUST** have the `title` and `detail` fields.
#### Example
### Example
```json
```javascript
{
"title": "Authentication required",
"detail": "Missing authentication credentials for the Greeting resource."
@@ -15,10 +16,10 @@ At the minimum, any Problem Detail response **MUST** have the `title` and `detai
```
## 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.
```json
```javascript
{
"type": "https://adidas-group.com/problems/scv/unauthorized",
"title": "Authentication required",
@@ -31,18 +32,20 @@ It **SHOULD** has the `type` field with the identifier of the error, besides it
> 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.
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.
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
### Example
Request:
```
```text
POST /my-resource HTTP/1.1
Content-Type: application/json
@@ -54,7 +57,7 @@ Content-Type: application/json
Response:
```
```text
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
Content-Language: en
@@ -64,7 +67,7 @@ Content-Language: en
"title": "Your request parameters didn't validate.",
"instance": "/my-resource",
"status": 400,
"errors": [
{
"type": "https://example.net/invalid_params",
@@ -82,20 +85,20 @@ Content-Language: en
}
```
## Problem Detail and Content Negotiation
#### Example
### 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
@@ -110,11 +113,14 @@ Content-Language: en
```
## 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)_
> __ [_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).
There are a whole plethora of libraries working with Problem Detail, for example, see [Zalando / Problem](https://github.com/zalando/problem) \(Java\).

View File

@@ -1,12 +1,14 @@
# 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
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:
```json
```javascript
{
"_links": {
"author": { "href": "/users/john" }
@@ -18,7 +20,7 @@ Use:
or:
```json
```javascript
{
...
"_embedded": {
@@ -33,7 +35,7 @@ or:
instead:
```json
```javascript
{
...
"authorHref": "/users/john"
@@ -41,12 +43,14 @@ instead:
```
## 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
### Example
Use:
```json
```javascript
{
"author": {
"id": "1234",
@@ -58,10 +62,11 @@ Use:
instead:
```json
```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.
> 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

@@ -1,22 +1,25 @@
# HAL
The [`application/hal+json`](http://stateless.co/hal_specification.html) (HAL) **MUST** be used as the representation format of a resource.
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!):
```json
The simplest Hal document looks like an empty JSON \(it is an empty JSON!\):
```javascript
{
}
```
A document representing a "Greeting" resource might look like:
```json
```javascript
{
"message": "Hello World!",
"_links": {
@@ -26,20 +29,22 @@ A document representing a "Greeting" resource might look like:
}
}
```
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).
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.
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).
> 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:
```json
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": {
@@ -56,14 +61,14 @@ A more complex document example could be an "Order" resource that has a related
```
## 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.
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:
```json
```javascript
{
"_links": {
"self": { "href": "/orders" }
@@ -87,28 +92,28 @@ The `_embedded` field's object just contains the related resources HAL represent
]
}
}
```
It is important to understand that embedded resource representation might be only **partial** and might also contain their own embedded resources.
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).
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`).
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/#/)
* [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).
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

@@ -1,13 +1,16 @@
# Message Formats
## Response Message Format
All **response** messages **MUST** support an [`application/hal+json`](http://stateless.co/hal_specification.html) (HAL) 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.
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.
**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

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

View File

@@ -1,24 +1,25 @@
# 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**.
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](core-principles/robustness.md). Use only the HTTP request methods, response codes and HTTP headers you understand, be liberal in accepting others.
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)
* [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).
@@ -27,8 +28,9 @@ Alternatively, you can download HTTP cheat sheets at [HTTP posters](https://gith
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)
> 1. [RFC 7231, HTTP/1.1: Semantics and Content](https://tools.ietf.org/html/rfc7231)
> 1. [RFC 7232, HTTP/1.1: Conditional Requests](https://tools.ietf.org/html/rfc7232)
> 1. [RFC 7233, HTTP/1.1: Range Requests](https://tools.ietf.org/html/rfc7233)
> 1. [RFC 7234, HTTP/1.1: Caching](https://tools.ietf.org/html/rfc7234)
> 1. [RFC 7235, HTTP/1.1: Authentication](https://tools.ietf.org/html/rfc7234)
> 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

@@ -1,32 +1,33 @@
# 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
1. _HTTP request method_ **MUST** be used to communicate the **action semantics** (intent and safety)
1. _HTTP response status_ code **MUST** be used to communicate the **information about the result** of the attempt to understand and satisfy the request
1. _HTTP message body_ **MUST** be used to transfer the **message content**
1. _HTTP message headers_ **MUST** be used to transfer the **metadata** about the message and its content
1. _URI query parameter_ **SHOULD NOT** be used to transfer metadata
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
#### 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.
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.
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
#### 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
...
@@ -38,12 +39,11 @@ Content-Type: application/json
}
```
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`.
---
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)_
> __ [_Heroku HTTP API Design Guide_](https://geemus.gitbooks.io/http-api-design/content/en/foundations/separate-concerns.html)

View File

@@ -1,4 +1,6 @@
# Transport Layer Security (TLS)
# 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.
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

@@ -1,45 +1,44 @@
# Use Appropriate Request Methods
# 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.
## 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.
## 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
### 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
#### Example 1
> GET /user/new
> Description: Creates new user
> 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”)
### Example 2
Using the POST method for a status update is **not acceptable** (use PATCH).
> POST /status Description: Updates the status of a user approval request \(to “Approved” or “Rejected”\)
#### Example 3
> PUT /user
> Description: Creates a new user
Using the POST method for a status update is **not acceptable** \(use PATCH\).
Using the PUT method for creating a new resource is **not acceptable** (use POST).
### Example 3
#### Example 4
> PUT: /user
> Description: Updates some user details
> PUT /user Description: Creates a new user
Using the PUT method for a partial update is **not acceptable** (use PATCH).
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

@@ -1,23 +1,25 @@
# Use Appropriate Status Codes
# 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
## Example
#### Use Codes 4xx or 5xx to Communicate Errors
A request:
## 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:
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
...
@@ -28,17 +30,19 @@ Content-Type: application/json
"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)
## Recommended Reading
* [How to Think About HTTP Status Codes](https://www.mnot.net/blog/2017/05/11/status_codes)

View File

@@ -0,0 +1,11 @@
# Guides
API-related guides:
* [API Design Process](https://tools.adidas-group.com/confluence/display/EA/API+Design+Process)
* Migration of Legacy Services \(SOAP\)
* API Testing with Dredd
* Continuous Integration / Deployment / Delivery
* [Apiary](https://help.apiary.io/api_101/understanding-apiary/)
* API Management

View File

@@ -0,0 +1,102 @@
# API Testing CI Environment
This guide describes steps necessary for testing an API described in a swagger file with the [Dredd API Testing Framework](https://github.com/apiaryio/dredd) in a CI Environment \(Jenkins, TeamCity\).
## Environment Prerequisites
The following must be available in the CI environment before testing:
1. **Node.js** runtime MUST be available in the CI environment:
```text
$ node -v
v7.5.0
```
2. **Ruby** runtime MUST be available in the CI environment:
```text
$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]
```
3. [**Dredd**](https://github.com/apiaryio/dredd) MUST be installed globally in the CI environment:
```text
$ npm install -g dredd --no-optional
```
```text
$ dredd --version
dredd v2.2.5 (Darwin 16.4.0; x64)
```
4. [**Apiary CLI Tool**](https://help.apiary.io/tools/apiary-cli) MUST be installed globally in the CI environment:
```text
$ gem install apiaryio
```
```text
$ apiary version
0.8.0
```
5. **Apiary API Key** MUST be set in the CI Environment environment variables:
```text
$ export APIARY_API_KEY=xyz
```
To obtain an Apiary API key, head to [https://login.apiary.io/tokens](https://login.apiary.io/tokens) \(NOTE: You will need the "ALL" Scope\)
## Testing an API
### Test Run Prerequisites
To test an API within the CI environment provisioned as mentioned in the environment prerequisites, you will need the following:
1. The name \(subdomain\) of API project at Apiary
```text
$ export APIARY_API_NAME=bomapi3
```
> See [How to find the Apiary API name](https://help.apiary.io/faq/find-api-name/) for more details.
2. A `swagger.yaml` file with the description of API being tested
To fetch the swagger.yaml file from Apiary run the following command before the test:
```text
$ apiary fetch --api-name=$APIARY_API_NAME --output="swagger.yaml"
```
The swagger document for Apiary project `bomapi3` was saved as local file `./swagger.yaml`.
> See [Fetching Published Documentation](https://help.apiary.io/tools/apiary-cli/#fetching-published-documentation).
3. The host \(address\) of the service being tested
```text
$ export API_HOST=http://deheremap7336.emea.adsint.biz:8004`
```
### Running the Test
With all of the above \(`APIARY_API_KEY`, `APIARY_API_NAME`, `API_HOST`, set up and `swagger.yaml` file present in the current directory\), run:
```text
$ dredd swagger.yaml $API_HOST -r apiary
```
> See [Dredd Command-line Interface](https://dredd.readthedocs.io/en/latest/usage-cli/).
The Dredd will perform the tests and exits usually if the tests have passed. You can check the test result as with any other Unix tools with:
```text
$ echo $?
```
Everything else but `0` should break the build. The test results will be visible in the CLI \(log\) as well as in Apiary.

View File

@@ -0,0 +1,112 @@
# Complete API Development
1. **Design the API**
1. Analyze business requirements
2. Identify affordances
> e.g.: Create user, Submit order, Search for an article
3. Identify resources
> e.g.: User, Order, Article
4. Identify relations
> e.g.: User has many Orders via order relation, all of the required affordances should be mapped to relations.
5. Formalize the design in the [Open API Specification](http://swagger.io/specification/) \(OAS, formerly known as "Swagger"\) format
6. Follow the [adidas API guidelines](https://adidas-group.gitbooks.io/api-guidelines/content/)
7. Put the OAS file into [Apiary adidas group](https://apiary.io)
8. Make sure the OAS file passes all adidas API Apiary style guide checks
9. Verify the design using Apiary Documentation and Apiary Mock Service
10. Review the API Design
11. Put the OAS file in a version control system \(VCS\) repository
12. Set up a CD pipeline to push OAS file from VCS to Apiary, whenever the file is changed
2. **Develop the API**
1. Check out the VCS repository with the OAS file
2. Set up the [Dredd API testing tool](https://github.com/apiaryio/dredd) locally
3. Configure the Dredd for your project
```text
$ dredd init
```
4. Run the Dredd test locally
> Against locally running API implementation, Every test should fail.
5. Implement the API
> Keep running the Dredd locally to see the progress.
6. Set up a [CI/CD pipeline](https://adidas-group.gitbooks.io/api-guidelines/content/guides/api-testing-ci-environment.html) to execute the Dredd tests automatically
> NOTE: Both TeamCity and Jenkins environments are available, contact adidas API evangelist for details.
3. **Deploy the API**
1. Deploy the service
2. Update the OAS file to add the deployment HOST
> ```text
> host: adidas.api.mashery.com
> basePath: /demo-approval-api
> ```
3. Verify the deployment with Dredd
> Use Dredd pointed towards the deployment host, be careful NOT to run it against the production OR using real production credentials.
4. Monitor the API usage "From performance and technical standpoint."
4. **Expose the API using Mashery**
1. **API**
1. Create new API Definition in Mashery
2. Create a new API Endpoint the API Definition
> Set the "Your Endpoint Address" to the internal deployment HOST.
3. Create a new API Package in Mashery
4. Create a new API Plan within the API Package
5. Use Mashery API Designer to add the newly created API Definitions' API Endpoint to the API Plan
6. Revisit the API Plan's API key default settings
7. Revisit the API Plan's API default rate limits
8. Revisit the API Plan's access policy/authorization
9. **API Documentation**
1. Create new adidas API developer's portal page in the Mashery
> Manage &gt; Content &gt; Documentation &gt; APIs
2. [Embed Apiary documentation](https://help.apiary.io/tools/embed/#apiary-embed-api-reference) on the newly created API Page
3. Revisit the API documentation access policy/authorization
5. **Use the API**
> This step can be done at the same time as "Develop the API" thank Apiary hosted Mock, Inspector, and Documentation.
1. Read API documentation at Apiary
2. Use API mock service provided by Apiary
3. Use API call inspector provided by Apiary
4. Obtain your API key
> The key is part of the API Plan created in Mashery and can be requested from your dashboard in the adidas API developer's portal.
5. When available use API implementation via Apiary proxy to debug the API calls
6. Use production deployment
6. **Analyze the API**
1. Examine the use of production API Using Mashery
2. Analyze the technical performance metrics
3. Collect the feedback from users
7. **Update API Design**
> Based on the analysis, new or changing business requirements
1. Create a new branch in the VCS repository with OAS file
2. Create a new project \(alternative\) in Apiary
3. Make sure the CI/CD pipeline is:
1. Set to push the OAS file to Apiary but make sure to modify the Apiary project name
2. Set to run Dredd test in the CI/CD
4. Modify the design \(OAS file\) accordingly, follow the "Design API" step
5. Follow the [**rules for extending**](https://adidas-group.gitbooks.io/api-guidelines/content/core-principles/rules-for-extending.html) and [**adidas API guidelines versioning policies**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/versioning.html)
6. Use VCS pull request \(PR\) to propose the change to review
7. After the API Design change is verified, reviewed and approved, continue with the "Develop the API" phase
8. Eventually, when the updated design is ready to be deployed for production, merge the branch into the production branch
9. Follow this guide from "Expose the API using Mashery" step

View File

@@ -1,7 +1,5 @@
# Miscellaneous
# Further References
* [Product tokens](https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-16#section-6.3)
* [Deprecating "X-"](https://tools.ietf.org/html/rfc6648)

View File

@@ -0,0 +1,4 @@
# Quality

View File

@@ -1,2 +1,4 @@
# Evolution
Evolution qualities, such as testability, maintainability, extensibility, and scalability.

View File

@@ -2,45 +2,52 @@
## General Naming Rules
- Use American English
- Don't use acronyms
- Use `camelCase` unless stated otherwise
- Reconcile terms with adidas CDM
* 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.
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 (`/`).
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](https://tools.adidas-group.com/confluence/display/EA/API+Interaction#APIInteraction-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.
> 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:
```json
A well-formed resource representation:
```javascript
{
"_links": {
"self": {
@@ -57,12 +64,14 @@ A well-formed resource representation:
```
## 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 (`-`).
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`:
```json
A well-formed resource representation with custom relation `fulfillment-provider`:
```javascript
{
"_links": {
"fulfillment-provider": {
@@ -72,22 +81,23 @@ A well-formed resource representation with custom relation `fulfillment-provider
}
```
## 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)).
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.
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
@@ -99,19 +109,24 @@ info:
```
### 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.
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.
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
```

View File

@@ -1,12 +1,16 @@
# Reserved Identifiers
The list of all reserved identifiers or identifiers with special meaning.
## Representation Format Fields
- `_links` - [HAL](https://adidas-group.gitbooks.io/api-guidelines/content/message/hal.html)
- `_embedded` - [HAL](https://adidas-group.gitbooks.io/api-guidelines/content/message/hal.html)
* `_links` - [HAL](https://adidas-group.gitbooks.io/api-guidelines/content/message/hal.html)
* `_embedded` - [HAL](https://adidas-group.gitbooks.io/api-guidelines/content/message/hal.html)
## Query Parameters
- `fields`- [Choosing Fields & Embedded Resources](https://adidas-group.gitbooks.io/api-guidelines/content/execution/choosing-fields-and-embedded-resoruces.html)
- `embedded` - [Choosing Fields & Embedded Resources](https://adidas-group.gitbooks.io/api-guidelines/content/execution/choosing-fields-and-embedded-resoruces.html)
- `offset` - [Pagination]()
- `limit`- [Pagination]()
* `fields`- [Choosing Fields & Embedded Resources](https://adidas-group.gitbooks.io/api-guidelines/content/execution/choosing-fields-and-embedded-resoruces.html)
* `embedded` - [Choosing Fields & Embedded Resources](https://adidas-group.gitbooks.io/api-guidelines/content/execution/choosing-fields-and-embedded-resoruces.html)
* `offset` - [Pagination](reserved-identifiers.md)
* `limit`- [Pagination](reserved-identifiers.md)

View File

@@ -1,3 +1,4 @@
# Testing Environments
# Testing Enviroments
Every API implementation **SHOULD** aim to provide a consistent, seamless way to create **test accounts** and access **test fixtures** to facilitate the development of API client applications.

View File

@@ -1,8 +1,10 @@
# URI Design
# 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.
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](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/naming-conventions.html).
To read more about the problematics refer to [RFC 7320: URI Design and Ownership](https://tools.ietf.org/html/rfc7320).

View File

@@ -2,7 +2,7 @@
> _The fundamental principle is that you cant break existing clients, because you dont know what they implement, and you dont 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)
> __ [_Mark Nottingham_](https://www.mnot.net/blog/2011/10/25/web_api_versioning_smackdown)
Any change to an API **MUST NOT** break existing clients.
@@ -21,7 +21,7 @@ A change **MUST NOT** affect **existing** resource identifiers \(name / URI\). F
> _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)
> __ [_Roy T. Fielding_](https://twitter.com/fielding/status/376835835670167552)
#### Example
@@ -49,13 +49,13 @@ If the media type conveys the version parameter, the version parameter **SHOULD*
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
```
@@ -98,5 +98,3 @@ API description \(OAS2\) files demonstrating a proposal of an backward-incompati
* [Evolving HTTP APIs](https://www.mnot.net/blog/2012/12/04/api-evolution)

View File

@@ -1,2 +1,4 @@
# Execution
Performance qualities, such as security and usability, which are observable at run time.

View File

@@ -1,25 +1,27 @@
# Asynchronous Tasks
If an API operation is asynchronous, but a client could track its progress, the response to such an asynchronous operation **MUST** return, in the case of success, the **202 Accepted** status code together with an `application/hal+json` representation of a new **task-tracking resource**.
## Task Tracking Resource
The task-tracking resource **SHOULD** convey the information about the status of an asynchronous task.
The task-tracking resource **SHOULD** convey the information about the status of an asynchronous task.
Retrieval of such a resource using the HTTP GET Request Method **SHOULD** be designed as follows:
1. Task is Still Processing
Return **200 OK** and representation of the current status.
Return **200 OK** and representation of the current status.
2. Task Successfully Completed
Return **303 See Other** together with [HTTP Location Header](https://tools.ietf.org/html/rfc7231#section-7.1.2) with URI or a outcome resource.
Return **303 See Other** together with [HTTP Location Header](https://tools.ietf.org/html/rfc7231#section-7.1.2) with URI or a outcome resource.
3. Task Failed
Return **200 OK** and `application/problem+json` with the problem detail information on the task has failed.
Return **200 OK** and `application/problem+json` with the problem detail information on the task has failed.
## Design Note
The asynchronous operation task-tracking resource can be either **polled** by client or the client might initially provide a **callback** to be executed when the operation finishes.
In the case of callback, the API and its client MUST agree on what HTTP method and request format is used for the callback invitation. If built within adidas, the "client" API is also the subject of the adidas API guidelines.

View File

@@ -1,12 +1,14 @@
# Batch Operations
## Processing Similar Resources
An operation that needs to process several related resources in bulk **SHOULD** use a collection resource with the appropriate HTTP Request Method. When processing existing resource the request message body **MUST** contain the URLs of the respective resources being processed.
#### Example
##### Create Multiple Orders at Once
### Example
```
#### Create Multiple Orders at Once
```text
POST /orders
Content-Type: application/json
@@ -22,11 +24,11 @@ Content-Type: application/json
}
```
#### Update Multiple Orders at Once
##### Update Multiple Orders at Once
> NOTE: The self-link relation identifies the existing resource being edited.
```
```text
PATCH /orders
Content-Type: application/json
@@ -49,36 +51,33 @@ Content-Type: application/json
```
## Results of Bulk Operation
Every bulk operation **MUST** be atomic and treated as any other operation.
> _The server must implement bulk requests as atomic. If the request is for creating ten addresses, the server should create all ten addresses before returning a successful response code. The server should not commit changes partially in the case of failures._
## DO NOT USE "POST Tunneling."
Every API **MUST** avoid tunneling multiple HTTP Request using one POST request. Instead, provide an application-specific resource to process the batch request.
## Non-atomic Bulk Operations
Non-atomic bulk operations are **strongly discouraged** as they bring additional burden and confusion to the client and are difficult to consume, debug, maintain and evolve over the time.
The suggestion is to **split** a non-atomic operation into several atomic operations. The cost of few more calls will be greatly outweighed but the cleaner design, clarity and easier maintainability.
However, in such an operation has to be provided such a non-atomic bulk operation **MUST** conform to the following guidelines.
1. Non-atomic bulk operation **MUST** return a success status code (e.g. **200 OK**) only if every and all sub-operation succeeded.
1. Non-atomic bulk operation **MUST** return a success status code \(e.g. **200 OK**\) only if every and all sub-operation succeeded.
2. If any single one sub-operation fails the whole non-atomic bulk operation **MUST** return the respective **4xx** or **5xx** status code.
3. In the case of a failure the response **MUST** contain the [problem detail](https://adidas-group.gitbooks.io/api-guidelines/content/message/error-reporting.html) information about every sub-operation that has failed.
4. **The client MUST be aware that the operation is non-atomic and the even the operation might have failed some sub-operations were processed successfully.**
1. If any single one sub-operation fails the whole non-atomic bulk operation **MUST** return the respective **4xx** or **5xx** status code.
1. In the case of a failure the response **MUST** contain the [problem detail](https://adidas-group.gitbooks.io/api-guidelines/content/message/error-reporting.html) information about every sub-operation that has failed.
1. **The client MUST be aware that the operation is non-atomic and the even the operation might have failed some sub-operations were processed successfully.**
#### Example
### Example
Non-atomic request for creating four orders:
```
```text
POST /orders
Content-Type: application/json
@@ -100,9 +99,9 @@ Content-Type: application/json
}
```
And the error response:
And the error response:
```
```text
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
@@ -110,7 +109,7 @@ Content-Type: application/problem+json
"type": "https://example.net/partial_operation_failure",
"title": "Partial Failure",
"detail": "Some orders couldn't be created, other orders were created.",
"errors": [
{
"type": "https://example.net/invalid-params",
@@ -130,7 +129,7 @@ Content-Type: application/problem+json
"processed": ...
}
```
The `processed` field should contain the result of processed sub-operations as if they were returned in a 200 OK.

View File

@@ -1,17 +1,20 @@
# Caching
Every API implementation **SHOULD** return both the cache expiry information ([`Cache-Control` HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control)) and specific resource version information ([`ETag` HTTP Header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)).
Every API implementation **SHOULD** return both the cache expiry information \([`Cache-Control` HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control)\) and specific resource version information \([`ETag` HTTP Header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)\).
## Cache-Control
Every API implementation's response **SHOULD** include information about cache-ability and cache expiration of the response. For HTTP 1.1 this is achieved using the `Cache-Control` header.
Every API implementation's response **SHOULD** include information about cache-ability and cache expiration of the response. For HTTP 1.1 this is achieved using the `Cache-Control` header.
### Common Cache-Control Scenarios
Two, most common scenarios for controlling the cache-ability of a response includes (1) Setting expiration and revalidation and (2) disabling the caching of a response. Refer to the [Cache-Control Documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) for additional controls.
Two, most common scenarios for controlling the cache-ability of a response includes \(1\) Setting expiration and revalidation and \(2\) disabling the caching of a response. Refer to the [Cache-Control Documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control) for additional controls.
#### 1. Cache Expiration & Revalidation
The common scenario to set cache expiration and revalidation policy is to use the `max-age` and `must-revalidate` directives:
```
```text
HTTP/1.1 200 OK
Date: Mon, 19 Aug 2017 00:00:00 CEST
Last-Modified: Mon, 19 Aug 2017 00:00:00 CEST
@@ -22,9 +25,10 @@ Content-Type: application/hal+json; charset=UTF-8
```
#### 2. Disabling Cache
To disable caching completely API implementation **SHOULD** use the `no-cache` and `no-store` directives:
```
To disable caching completely API implementation **SHOULD** use the `no-cache` and `no-store` directives:
```text
HTTP/1.1 200 OK
Date: Mon, 19 Aug 2017 00:00:00 CEST
Last-Modified: Mon, 19 Aug 2017 00:00:00 CEST
@@ -35,11 +39,14 @@ Content-Type: application/hal+json; charset=UTF-8
```
## ETag
Every API implementation's response to a [cacheable request](https://github.com/for-GET/know-your-http-well/blob/master/methods.md#cacheable) **SHOULD** include the [`ETag` HTTP Header](https://tools.ietf.org/html/rfc7232#section-2.3) to identify the specific version of the returned resource.
Every API client **SHOULD** use [`If-None-Match` HTTP header](https://tools.ietf.org/html/rfc7232#section-3.2) whenever it's performing a cacheable request. The value of `If-None-Match` should be the value of the `ETag` header stored from a previous request. The client **MUST** be ready to handle the **304 Not Modified** response from the server to use the legal copy.
#### How ETag works
ETags are unique identifiers for a particular version of a resource found by a URL. They are used for cache validation, to check for modifications quickly.
A client requests a resource from the server at a particular URI. The server responds with the specific ETag value in the HTTP ETag header field. ETag and the resource will be stored locally by the client. Subsequent requests from the client are done with the If-None-Match header, which now contains the ETag value from the previous request. The server now compares the values. If they are the same, it responds with HTTP Status Code 304 Not Modified. If not, the resource is sent.

View File

@@ -1,22 +1,25 @@
# Choosing Fields & Embedded Resources
# Choosing Fields and Embedded Resources
## Response Message Fields
Every request that may result in a response with a non-trivial body **SHOULD** implement the `fields` query parameter. If provided, the value of this parameter must be a comma-separated list of top-level response message fields.
Upon receiving such a request, in the event of a 2xx response, the service **SHOULD** respond with a message that includes only top-level fields specified in the `fields` parameter. That includes HAL-specific fields (`_links` and `_embedded`).
Every request that may result in a response with a non-trivial body **SHOULD** implement the `fields` query parameter. If provided, the value of this parameter must be a comma-separated list of top-level response message fields.
Upon receiving such a request, in the event of a 2xx response, the service **SHOULD** respond with a message that includes only top-level fields specified in the `fields` parameter. That includes HAL-specific fields \(`_links` and `_embedded`\).
### Example
#### Example
Retrieve only some details of an Order resource:
HTTP Request
```
```text
GET /order/1234?fields=_links,orderNumber,status HTTP/1.1
Accept: application/hal+json
```
HTTP Response
```
```text
HTTP/1.1 200 OK
Content-Type: application/hal+json
@@ -32,23 +35,25 @@ Content-Type: application/hal+json
```
## Embedded Resources
Similarly to the `fields` query parameter, every request that might result in a response containing related embedded resource representations **SHOULD** implement the `embedded` query parameter. If, provided the value of the `embedded` query parameter **MUST** be a comma-separated list of relation identifiers.
Upon receiving such a request, in the event of a 2xx response, the service **SHOULD** respond with a message that "embeds" (see HAL `_embedded` field) only the related resources specified in the `embedded` parameter.
Upon receiving such a request, in the event of a 2xx response, the service **SHOULD** respond with a message that "embeds" \(see HAL `_embedded` field\) only the related resources specified in the `embedded` parameter.
### Example
#### Example
Embed only information about the Author of an Order resource. We are not interested in Items that are in this order.
HTTP Request
```
```text
GET /order/1234?embed=author HTTP/1.1
Accept: application/hal+json
```
HTTP Response
```
```text
HTTP/1.1 200 OK
Content-Type: application/hal+json
@@ -72,9 +77,12 @@ Content-Type: application/hal+json
```
## Reasonable Defaults
When `fields` and `embedded` parameters are not provided or not implemented the server **SHOULD** return reasonable default field and/or embedded resources. The defaults **MUST** always contain the `_links` field, where available.
## Resource Variants
The facility of `fields` and `embedded` parameters doesn't impose any restriction of creating new resource variants.
It is OK to create a new resource just as a compound resource only to provide selected fields or blend-embed some existing resources together.
The facility of `fields` and `embedded` parameters doesn't impose any restriction of creating new resource variants.
It is OK to create a new resource just as a compound resource only to provide selected fields or blend-embed some existing resources together.

View File

@@ -1,16 +1,17 @@
# Localization
## Language Variants
If a resource has multiple language variants and the difference between variants is only in the language of human-readable fields, then the [`Accept-Language`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language) request HTTP header **SHOULD** be used to select the desired language variant.
#### Example
### Example
```
```text
GET /article HTTP/1.1
Accept-Language: en,en-US,fr;q=0.6
```
```
```text
HTTP/1.1 200 OK
Content-Type: application/hal+json;charset=UTF-8
Content-Language: en
@@ -20,14 +21,16 @@ Vary: Accept-Language
```
## Language or Country-specific Data Structure
If the difference between language or country specific variants of a resource is bigger than just in the content of human readable strings, for example, the data structure of the resource representation is different, then a query parameter **SHOULD** be used to communicate the requested variant.
#### Example
If the difference between language or country specific variants of a resource is bigger than just in the content of human readable strings, for example, the data structure of the resource representation is different, then a query parameter **SHOULD** be used to communicate the requested variant.
```
### Example
```text
GET /article?market=en_US HTTP/1.1
```
```
```text
HTTP/1.1 200 OK
Content-Type: application/hal+json;charset=UTF-8
Content-Language: en
@@ -35,3 +38,4 @@ Vary: Accept-Language
...
```

View File

@@ -1,11 +1,12 @@
# Pagination
A collection resource **SHOULD** provide the [`first`, `last`, `next` and `prev` link](https://tools.ietf.org/html/rfc5988#section-6.2.2)s for navigation within the collection.
#### Example
## Example
The Collection of Orders using the collection navigation link and `offset` and `limit` query parameters:
```json
```javascript
{
"_links": {
"self": { "href": "/orders?offset=100&limit=10" },
@@ -19,9 +20,10 @@ The Collection of Orders using the collection navigation link and `offset` and `
"order": [
{ ... },
{ ... },
...
]
}
}
```

View File

@@ -1,17 +1,17 @@
# Query Requests with Large Inputs
While HTTP doesn't impose any limit on the length of a URI, some implementation of server or client might have difficulties handling long URIs (usually URIs with many or large query parameters).
While HTTP doesn't impose any limit on the length of a URI, some implementation of server or client might have difficulties handling long URIs \(usually URIs with many or large query parameters\).
Every endpoint with such a URI **MUST** use the HTTP **POST** Request Method and send the query string in HTTP Request Message body using the `application/x-www-form-urlencoded` media type.
## Example
#### Example
```
```text
POST /orders HTTP/1.1
Content-Type: application/x-www-form-urlencoded
search=attributes&color=white&size=56&...
```
> _NOTE: Since this operation is safe and idempotent, using the POST method violates the HTTP protocol semantics and results in loss of cache-ability._

View File

@@ -1,15 +1,18 @@
# Rate Limiting
The API rate limiting is provided by the selected adidas API management platform Mashery.
Rate limit information is provided in the for of HTTP headers. There are two types of rate limits: **Quota** and **Throttle**. The quota is a limit enforced per a longer period (typically a day). The throttle is the limit of calls per second.
The API rate limiting is provided by the selected adidas API management platform Mashery.
Rate limit information is provided in the for of HTTP headers. There are two types of rate limits: **Quota** and **Throttle**. The quota is a limit enforced per a longer period \(typically a day\). The throttle is the limit of calls per second.
## Quota Limit
The limit on the number of calls per a period (day). The default quota limit is 5000 calls per day.
#### Example
Example response to a request over the quota limit:
The limit on the number of calls per a period \(day\). The default quota limit is 5000 calls per day.
```
### Example
Example response to a request over the quota limit:
```text
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
@@ -20,16 +23,17 @@ X-Mashery-Error-Code: ERR_403_DEVELOPER_OVER_RATE
"title": "Rate Limit Exceeded",
"detail": "Account Over Rate Limit"
}
```
## Throttle Limit
The limit on the number of calls per second. The default throttle limit is two calls per second.
#### Example
The limit on the number of calls per second. The default throttle limit is two calls per second.
### Example
Example response to a request over the throttle limit:
```
```text
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
@@ -43,16 +47,17 @@ X-Mashery-Error-Code: ERR_403_DEVELOPER_OVER_QPS
}
```
> NOTE: The `Retry-After` gives a hint how long before the same request should be repeated (in seconds).
> NOTE: The `Retry-After` gives a hint how long before the same request should be repeated \(in seconds\).
## Detail Information
By default, the headers do not contain details about the current usage and quotas. The default can be changed in the API management.
#### Example
A successful response with the details about throttle (`X-Plan-QPS`) and quota (`X-Plan-Quota`) rate limits:
### Example
```
A successful response with the details about throttle \(`X-Plan-QPS`\) and quota \(`X-Plan-Quota`\) rate limits:
```text
HTTP/1.1 200 OK
X-Plan-QPS-Allotted: 10
@@ -61,3 +66,4 @@ X-Plan-Quota-Allotted: 1000
X-Plan-Quota-Current: 2
X-Plan-Quota-Reset: Tuesday, June 6, 2017 12:00:00 AM GMT
```

View File

@@ -1,10 +1,11 @@
# Search Requests
A search (filter) operation on a collection resource **SHOULD** be defined as safe, idempotent and cacheable, therefore using the [GET HTTP request method](https://adidas-group.gitbooks.io/api-guidelines/content/protocol/use-appropriate-methods.html).
A search \(filter\) operation on a collection resource **SHOULD** be defined as safe, idempotent and cacheable, therefore using the [GET HTTP request method](https://adidas-group.gitbooks.io/api-guidelines/content/protocol/use-appropriate-methods.html).
Every search parameter **SHOULD** be provided in the form of a query parameter. In the case of search parameters being mutually exclusive or require the presence of another parameter, the explanation **MUST** be part of operation's description.
### Example
#### Example
A collection of orders can be filtered by either article id it includes or by article manufacturer id. The two parameters are mutually exclusive and cannot be used together. The API description for such a design should look as follows:
```yaml
@@ -15,41 +16,43 @@ paths:
get:
summary: Retrieve or Search in the Collection of Orders
description: |
This operation allows to retrieve a filtered list of orders based on multiple criteria:
1. **Filter Orders by Article Id**
2. **Filter Orders by Manufacturer Id**
parameters:
- name: article_id
in: query
description: |
Article Id. Denotes the id of an article that must be in the order.
**Mutually exclusive** with `manufacturer_id`.
required: false
type: string
x-example: article_id_1
- name: manufacturer_id
in: query
description: |
Manufacturer Id. Denotes an id of a manufacturer of an article that must be in the order.
**Mutually exclusive** with `article_id`.
required: false
type: string
x-example: manufacturer_id_1
x-example: manufacturer_id_1
```
## Alternative Design
When it would be beneficial (e.g. one of the filter queries is more common than another one) a separate resource for the particular query **SHOULD** be provided. In such a case, the pivotal search parameter **MAY** be in the form of a path variable.
#### Example
Building on top of the example mentioned above, we will provide the filtering of orders by article id as a separate resource.
When it would be beneficial \(e.g. one of the filter queries is more common than another one\) a separate resource for the particular query **SHOULD** be provided. In such a case, the pivotal search parameter **MAY** be in the form of a path variable.
### Example
Building on top of the example mentioned above, we will provide the filtering of orders by article id as a separate resource.
```yaml
paths:
@@ -59,3 +62,4 @@ paths:
get:
summary: Retrieve the collection of Orders that contain given article.
```

View File

@@ -1,8 +1,10 @@
# ![](/assets/adidas-logo.svg)
# Introduction
# adidas REST API Guidelines
## ![](../.gitbook/assets/adidas-logo.svg)
The adidas REST API Guidelines defines standards and guidelines for building REST APIs at adidas. **These Guidelines has to be followed in addition to the adidas **[**General API Guidelines.**](/general-guidelines/README.md)
## adidas REST API Guidelines
The adidas REST API Guidelines defines standards and guidelines for building REST APIs at adidas. **These Guidelines has to be followed in addition to the adidas** [**General API Guidelines.**](../general-guidelines/general-guidelines.md)
The REST API Guidelines are further split into the following parts:
@@ -11,7 +13,6 @@ The REST API Guidelines are further split into the following parts:
REST API Guidelines Core Principles defines the rules that **MUST** be followed at throughout the full API lifecycle.
* **Functionality Guidelines**
* [**Protocol level**](https://adidas-group.gitbooks.io/api-guidelines/content/protocol/)
Protocol guidelines define the protocols used within the organization.
@@ -23,7 +24,6 @@ The REST API Guidelines are further split into the following parts:
* [**Application level**](https://adidas-group.gitbooks.io/api-guidelines/content/application/)
The Application guidelines define the definition and use of application-specific semantics.
* **Quality Guidelines**
Evolution and Execution guidelines define the rules for achieving the desired architectural qualities of systems.
@@ -36,12 +36,8 @@ The REST API Guidelines are further split into the following parts:
Execution qualities governance, such as security and usability.
* **Guides**
Guides and materials supporting the REST API Guidelines
* **Guides** Guides and materials supporting the REST API Guidelines
* **API Clients**
Section dedicated to consumers of adidas APIs

View File

@@ -1,4 +0,0 @@
# Application-level Semantics
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

@@ -1,4 +0,0 @@
# Loose Coupling
In addition to the [robustness principle](core-principles/robustness.md), API consumers (clients) **MUST** **operate independently** on API implementation's internals. Similarly the API consumers **MUST NOT** **assume** or **rely on** any knowledge of the API service internal implementation.
Where available, the clients **SHOULD** utilize **hypermedia controls as the engine of the application state**, and rely on the **protocol, message and vocabulary semantics**.

View File

@@ -1,16 +0,0 @@
# API Design Platform - Apiary
1. [Apiary](https://apiary.io/) is the primary platform supporting [API first approach](./api-first.md). Apiary **MUST** be used during API Design.
2. Every API description **MUST** be stored in [Apiary](https://apiary.io/) under the ADIDAS GROUP team.
3. Apiary **MUST** be the **single source of truth** to learn about existing APIs within the organization.
> NOTE: Apiary supports API-first approach in multiple ways:
> a. Validates API description for correctness and automatically generates API documentation to drive the discussion between stakeholders. \(No more emails with API description flying between stakeholders\)
>
> NOTE: The synchronization between the version control system and adidas [API Description platform](./apiary.md)
> should be automated using CI/CD framework.

View File

@@ -1,16 +0,0 @@
# Design & Implementation Maturity
## API Design Maturity
> How to design an API
Every API design **MUST** be **resource-centric** ([Web API Design Maturity Model Level 2](http://amundsen.com/talks/2016-11-apistrat-wadm/2016-11-apistrat-wadm.pdf)). That is an API design **MUST** revolve around Web-styled _resources_, _relations_ between the resources and the _actions_ the resources may afford.
An API design **MAY** be **affordance-centric** ([Web API Design Maturity Model Level 3](http://amundsen.com/talks/2016-11-apistrat-wadm/2016-11-apistrat-wadm.pdf)).
## API Design Implementation Maturity
> How to implement the API design
Every API design implementation using the HTTP protocol **MUST** use the appropriate **HTTP Request Method** ([Richardson Maturity Model Level 2](https://martinfowler.com/articles/richardsonMaturityModel.html#level2)) to implement an action afforded by a resource.
An API design implementation **SHOULD** include **hypermedia controls** (HATEOAS) ([Richardson Maturity Model Level 3](https://martinfowler.com/articles/richardsonMaturityModel.html#level3)).

View File

@@ -1,4 +0,0 @@
# Testing Contract Validation
Every API description (contract) using HTTP(S) protocol **MUST** be tested against its API implementation. The tests **MUST** be executed using the [Dredd testing framework](https://github.com/apiaryio/dredd). The Dredd **MUST** [report the test results to Apiary](https://help.apiary.io/tools/automated-testing/testing-reporter/).
In addition to local runs, the tests **SHOULD** be an integral part the API implementation's CI/CD pipeline. The CI/CD pipeline **SHOULD** be configured to run the test whenever there is a change to either API description (contract) or its implementation.

View File

@@ -1,9 +0,0 @@
# Guides
API-related guides:
- [API Design Process](https://tools.adidas-group.com/confluence/display/EA/API+Design+Process)
- Migration of Legacy Services (SOAP)
- API Testing with Dredd
- Continuous Integration / Deployment / Delivery
- [Apiary](https://help.apiary.io/api_101/understanding-apiary/)
- API Management

View File

@@ -1,101 +0,0 @@
# Jenkins CI Environment for Apiary Project
This guide describes steps necessary for testing an API described in a swagger file with the [Dredd API Testing Framework](https://github.com/apiaryio/dredd) in a CI Environment (Jenkins, TeamCity).
## Environment Prerequisites
The following must be available in the CI environment before testing:
1. **Node.js** runtime MUST be available in the CI environment:
```
$ node -v
v7.5.0
```
1. **Ruby** runtime MUST be available in the CI environment:
```
$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]
```
1. [**Dredd**](https://github.com/apiaryio/dredd) MUST be installed globally in the CI environment:
```
$ npm install -g dredd --no-optional
```
```
$ dredd --version
dredd v2.2.5 (Darwin 16.4.0; x64)
```
1. [**Apiary CLI Tool**](https://help.apiary.io/tools/apiary-cli) MUST be installed globally in the CI environment:
```
$ gem install apiaryio
```
```
$ apiary version
0.8.0
```
1. **Apiary API Key** MUST be set in the CI Environment environment variables:
```
$ export APIARY_API_KEY=xyz
```
To obtain an Apiary API key, head to <https://login.apiary.io/tokens> (NOTE: You will need the "ALL" Scope)
## Testing an API
### Test Run Prerequisites
To test an API within the CI environment provisioned as mentioned in the environment prerequisites, you will need the following:
1. The name (subdomain) of API project at Apiary
```
$ export APIARY_API_NAME=bomapi3
```
> See [How to find the Apiary API name](https://help.apiary.io/faq/find-api-name/) for more details.
1. A `swagger.yaml` file with the description of API being tested
To fetch the swagger.yaml file from Apiary run the following command before the test:
```
$ apiary fetch --api-name=$APIARY_API_NAME --output="swagger.yaml"
```
The swagger document for Apiary project `bomapi3` was saved as local file `./swagger.yaml`.
> See [Fetching Published Documentation](https://help.apiary.io/tools/apiary-cli/#fetching-published-documentation).
1. The host (address) of the service being tested
```
$ export API_HOST=http://deheremap7336.emea.adsint.biz:8004`
```
### Running the Test
With all of the above (`APIARY_API_KEY`, `APIARY_API_NAME`, `API_HOST`, set up and `swagger.yaml` file present in the current directory), run:
```
$ dredd swagger.yaml $API_HOST -r apiary
```
> See [Dredd Command-line Interface](https://dredd.readthedocs.io/en/latest/usage-cli/).
The Dredd will perform the tests and exits usually if the tests have passed. You can check the test result as with any other Unix tools with:
```
$ echo $?
```
Everything else but `0` should break the build. The test results will be visible in the CLI (log) as well as in Apiary.

View File

@@ -1,162 +0,0 @@
# The Complete API Development Guide
1. **Design the API**
1. Analyze business requirements
1. Identify affordances
> e.g.: Create user, Submit order, Search for an article
1. Identify resources
> e.g.: User, Order, Article
1. Identify relations
> e.g.: User has many Orders via order relation, all of the required affordances should be mapped to relations.
1. Formalize the design in the [Open API Specification](http://swagger.io/specification/) (OAS, formerly known as "Swagger") format
1. Follow the [adidas API guidelines](https://adidas-group.gitbooks.io/api-guidelines/content/)
1. Put the OAS file into [Apiary adidas group](https://apiary.io)
1. Make sure the OAS file passes all adidas API Apiary style guide checks
1. Verify the design using Apiary Documentation and Apiary Mock Service
1. Review the API Design
1. Put the OAS file in a version control system (VCS) repository
1. Set up a CD pipeline to push OAS file from VCS to Apiary, whenever the file is changed
1. **Develop the API**
1. Check out the VCS repository with the OAS file
1. Set up the [Dredd API testing tool](https://github.com/apiaryio/dredd) locally
1. Configure the Dredd for your project
```
$ dredd init
```
1. Run the Dredd test locally
> Against locally running API implementation, Every test should fail.
1. Implement the API
> Keep running the Dredd locally to see the progress.
1. Set up a [CI/CD pipeline](https://adidas-group.gitbooks.io/api-guidelines/content/guides/api-testing-ci-environment.html) to execute the Dredd tests automatically
> NOTE: Both TeamCity and Jenkins environments are available, contact adidas API evangelist for details.
1. **Deploy the API**
1. Deploy the service
1. Update the OAS file to add the deployment HOST
> ```
> host: adidas.api.mashery.com
> basePath: /demo-approval-api
> ```
1. Verify the deployment with Dredd
> Use Dredd pointed towards the deployment host, be careful NOT to run it against the production OR using real production credentials.
1. Monitor the API usage
"From performance and technical standpoint."
1. **Expose the API using Mashery**
1. **API**
1. Create new API Definition in Mashery
1. Create a new API Endpoint the API Definition
> Set the "Your Endpoint Address" to the internal deployment HOST.
1. Create a new API Package in Mashery
1. Create a new API Plan within the API Package
1. Use Mashery API Designer to add the newly created API Definitions' API Endpoint to the
API Plan
1. Revisit the API Plan's API key default settings
1. Revisit the API Plan's API default rate limits
1. Revisit the API Plan's access policy/authorization
1. **API Documentation**
1. Create new adidas API developer's portal page in the Mashery
> Manage > Content > Documentation > APIs
1. [Embed Apiary documentation](https://help.apiary.io/tools/embed/#apiary-embed-api-reference) on the newly created API Page
1. Revisit the API documentation access policy/authorization
1. **Use the API**
> This step can be done at the same time as "Develop the API" thank Apiary hosted Mock, Inspector, and Documentation.
1. Read API documentation at Apiary
1. Use API mock service provided by Apiary
1. Use API call inspector provided by Apiary
1. Obtain your API key
> The key is part of the API Plan created in Mashery and can be requested from your dashboard in the adidas API developer's portal.
1. When available use API implementation via Apiary proxy to debug the API calls
1. Use production deployment
1. **Analyze the API**
1. Examine the use of production API Using Mashery
1. Analyze the technical performance metrics
1. Collect the feedback from users
1. **Update API Design**
> Based on the analysis, new or changing business requirements
1. Create a new branch in the VCS repository with OAS file
1. Create a new project (alternative) in Apiary
1. Make sure the CI/CD pipeline is:
1. Set to push the OAS file to Apiary but make sure to modify the Apiary project name
1. Set to run Dredd test in the CI/CD
1. Modify the design (OAS file) accordingly, follow the "Design API" step
1. Follow the [**rules for extending**](https://adidas-group.gitbooks.io/api-guidelines/content/core-principles/rules-for-extending.html) and [**adidas API guidelines versioning policies**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/versioning.html)
1. Use VCS pull request (PR) to propose the change to review
1. After the API Design change is verified, reviewed and approved, continue with the "Develop the API" phase
1. Eventually, when the updated design is ready to be deployed for production, merge the branch into the production branch
1. Follow this guide from "Expose the API using Mashery" step

View File

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