From b7669f3c92b3396122365bb9f99030a5db37b3b1 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 11:52:22 +0000 Subject: [PATCH 01/17] Updates README.md Auto commit by GitBook Editor --- README.md | 77 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index a12be97..742a29b 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,62 @@ ![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/)) + +_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 several levels: -- **[Core Principles](https://adidas-group.gitbooks.io/api-guidelines/content/core-principles/)** +The API Guidelines are split into two main parts: - Core Principles define the general rules that MUST be followed at throughout the full API lifecycle at any level. +* General Guidelines +* API type-specific Guidelines -- **Functionality Guidelines** - - **[Protocol level](https://adidas-group.gitbooks.io/api-guidelines/content/protocol/)** - - Protocol guidelines define the protocols used within the organization. - - - **[Message level](https://adidas-group.gitbooks.io/api-guidelines/content/message/)** - - The Message guidelines define the structure and semantics of messages used to exchange information. - - - **[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. - - - **[Evolution](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/)** - - Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. - - - **[Execution](https://adidas-group.gitbooks.io/api-guidelines/content/execution/)** - - Execution qualities governance, such as security and usability. +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 + +* The API Guidelines are split into several levels: + +* [**Core Principles**](https://adidas-group.gitbooks.io/api-guidelines/content/core-principles/) + + Core Principles define the general rules that MUST be followed at throughout the full API lifecycle at any level. + +* **Functionality Guidelines** + + * [**Protocol level**](https://adidas-group.gitbooks.io/api-guidelines/content/protocol/) + + Protocol guidelines define the protocols used within the organization. + + * [**Message level**](https://adidas-group.gitbooks.io/api-guidelines/content/message/) + + The Message guidelines define the structure and semantics of messages used to exchange information. + + * [**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. + + * [**Evolution**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/) + + Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. + + * [**Execution**](https://adidas-group.gitbooks.io/api-guidelines/content/execution/) + + Execution qualities governance, such as security and usability. + +## 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: > ``` @@ -55,6 +67,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._ From 106ccf2e5fee8aaf1bcb2f3a21098356280dabd3 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 12:03:13 +0000 Subject: [PATCH 02/17] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index 1facd27..8cf058a 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -1,17 +1,27 @@ # Summary +## Introduction + * [Introduction](README.md) -* [Core Principles](core-principles/README.md) - * [API First](core-principles/api-first.md) - * [OpenAPI Specification](core-principles/openapi-specification.md) - * [API Design Platform](core-principles/apiary.md) - * [Version Control System](core-principles/version-control-system.md) - * [Contract](core-principles/contract.md) - * [Testing](core-principles/testing.md) - * [Design Maturity](core-principles/design-maturity.md) - * [Robustness](core-principles/robustness.md) - * [Minimal API Surface](core-principles/minimal-api-surface.md) - * [Rules for Extending](core-principles/rules-for-extending.md) + +## General Guidelines + +* [API First](core-principles/api-first.md) +* [Contract](core-principles/contract.md) +* [Version Control System](core-principles/version-control-system.md) +* [Robustness](core-principles/robustness.md) +* [Minimal API Surface](core-principles/minimal-api-surface.md) +* [Rules for Extending](core-principles/rules-for-extending.md) +* [Foreign Key Relations](message/foreign-key-relations.md) +* [JSON](evolution/json.md) +* [Security](execution/security.md) + +## REST APIs + +* [OpenAPI Specification](core-principles/openapi-specification.md) +* [API Design Platform](core-principles/apiary.md) +* [Design Maturity](core-principles/design-maturity.md) +* [Testing](core-principles/testing.md) * [Protocol](protocol/README.md) * [HTTP](protocol/http.md) * [TLS](protocol/tls.md) @@ -23,14 +33,12 @@ * [Content Negotiation](message/content-negotiation.md) * [HAL](message/hal.md) * [Problem Detail](message/error-reporting.md) - * [Foreign Key Relations](message/foreign-key-relations.md) * [Application](application/README.md) * [Corporate Data Model](application/harmonize-data.md) * [Common Data Types](application/common-data-types.md) * [Evolution](evolution/README.md) - * [Naming Conventions](evolution/naming-conventions.md) * [Reserved Identifiers](evolution/reserved-identifiers.md) - * [JSON](evolution/json.md) + * [Naming Conventions](evolution/naming-conventions.md) * [Changes and Versioning](evolution/versioning.md) * [URI Structure](evolution/uri-structure.md) * [Testing Enviroments](execution/testing-enviroments.md) @@ -42,15 +50,15 @@ * [Query Requests with Large Inputs](execution/query-requests-with-large-inputs.md) * [Choosing Fields and Embedded Resources](execution/choosing-fields-and-embedded-resoruces.md) * [Localization](execution/localization.md) - * [Security](execution/security.md) * [Rate Limiting](execution/rate-limiting.md) * [Caching](execution/caching.md) -* [API Clients](clients/README.md) - * [Loose Coupling](clients/loose-coupling.md) * [Guides](guides/README.md) * [API Testing CI Environment](guides/api-testing-ci-environment.md) * [Complete API Development](guides/complete-api-development.md) +* [API Clients](clients/README.md) + * [Loose Coupling](clients/loose-coupling.md) * [Examples](examples.md) * [Miscellaneous](miscellaneous.md) -* [Acknowledgements](acknowledgements.md) + +## Kafka From 8dca3288ea593ee4a70c83d8ddd9e73927c5f453 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 12:03:42 +0000 Subject: [PATCH 03/17] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SUMMARY.md b/SUMMARY.md index 8cf058a..ae7eb6f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -2,7 +2,7 @@ ## Introduction -* [Introduction](README.md) +* [Welcome](README.md) ## General Guidelines From c8fac2ccbcc7c3237583a20a095f978eab68c550 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 12:05:02 +0000 Subject: [PATCH 04/17] Updates kafka/introduction.md Auto commit by GitBook Editor --- SUMMARY.md | 3 +++ core-principles/introduction.md | 0 kafka/introduction.md | 2 ++ 3 files changed, 5 insertions(+) create mode 100644 core-principles/introduction.md create mode 100644 kafka/introduction.md diff --git a/SUMMARY.md b/SUMMARY.md index ae7eb6f..66314ba 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -18,6 +18,7 @@ ## REST APIs +* [Introduction](core-principles/introduction.md) * [OpenAPI Specification](core-principles/openapi-specification.md) * [API Design Platform](core-principles/apiary.md) * [Design Maturity](core-principles/design-maturity.md) @@ -62,3 +63,5 @@ ## Kafka +* [Introduction](kafka/introduction.md) + diff --git a/core-principles/introduction.md b/core-principles/introduction.md new file mode 100644 index 0000000..e69de29 diff --git a/kafka/introduction.md b/kafka/introduction.md new file mode 100644 index 0000000..65a172c --- /dev/null +++ b/kafka/introduction.md @@ -0,0 +1,2 @@ +Apache Kafka at adidas + From a49d236a03c09682597ec86d7e9055d239b084ab Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 12:16:40 +0000 Subject: [PATCH 05/17] Updates core-principles/apiary.md Auto commit by GitBook Editor --- README.md | 34 -------------------- SUMMARY.md | 6 ++-- core-principles/api-first.md | 4 +-- core-principles/apiary.md | 17 ++++++---- core-principles/contract.md | 8 +++-- core-principles/core-principles.md | 0 core-principles/introduction.md | 38 +++++++++++++++++++++++ core-principles/version-control-system.md | 5 +-- kafka/introduction.md | 4 ++- 9 files changed, 63 insertions(+), 53 deletions(-) create mode 100644 core-principles/core-principles.md diff --git a/README.md b/README.md index 742a29b..91d8037 100644 --- a/README.md +++ b/README.md @@ -19,40 +19,6 @@ The API Guidelines are split into two main parts: 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\). - - -* The API Guidelines are split into several levels: - -* [**Core Principles**](https://adidas-group.gitbooks.io/api-guidelines/content/core-principles/) - - Core Principles define the general rules that MUST be followed at throughout the full API lifecycle at any level. - -* **Functionality Guidelines** - - * [**Protocol level**](https://adidas-group.gitbooks.io/api-guidelines/content/protocol/) - - Protocol guidelines define the protocols used within the organization. - - * [**Message level**](https://adidas-group.gitbooks.io/api-guidelines/content/message/) - - The Message guidelines define the structure and semantics of messages used to exchange information. - - * [**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. - - * [**Evolution**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/) - - Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. - - * [**Execution**](https://adidas-group.gitbooks.io/api-guidelines/content/execution/) - - Execution qualities governance, such as security and usability. - ## 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). diff --git a/SUMMARY.md b/SUMMARY.md index 66314ba..7d9410f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -2,7 +2,7 @@ ## Introduction -* [Welcome](README.md) +* [adidas API Guidelines](README.md) ## General Guidelines @@ -12,7 +12,6 @@ * [Robustness](core-principles/robustness.md) * [Minimal API Surface](core-principles/minimal-api-surface.md) * [Rules for Extending](core-principles/rules-for-extending.md) -* [Foreign Key Relations](message/foreign-key-relations.md) * [JSON](evolution/json.md) * [Security](execution/security.md) @@ -34,6 +33,7 @@ * [Content Negotiation](message/content-negotiation.md) * [HAL](message/hal.md) * [Problem Detail](message/error-reporting.md) + * [Foreign Key Relations](message/foreign-key-relations.md) * [Application](application/README.md) * [Corporate Data Model](application/harmonize-data.md) * [Common Data Types](application/common-data-types.md) @@ -59,7 +59,7 @@ * [API Clients](clients/README.md) * [Loose Coupling](clients/loose-coupling.md) * [Examples](examples.md) -* [Miscellaneous](miscellaneous.md) +* Core Principles ## Kafka diff --git a/core-principles/api-first.md b/core-principles/api-first.md index a712717..03a1353 100644 --- a/core-principles/api-first.md +++ b/core-principles/api-first.md @@ -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 description 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 description 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. diff --git a/core-principles/apiary.md b/core-principles/apiary.md index 33b1e08..aa4985e 100644 --- a/core-principles/apiary.md +++ b/core-principles/apiary.md @@ -2,10 +2,15 @@ 1. [Apiary](https://apiary.io/) is the primary platform supporting [API first approach](./api-first.md). Apiary **MUST** be used during API Design. -1. Every API description **MUST** be stored in [Apiary](https://apiary.io/) under the ADIDAS GROUP team. +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. + + -1. 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) - diff --git a/core-principles/contract.md b/core-principles/contract.md index a96c25e..f960c23 100644 --- a/core-principles/contract.md +++ b/core-principles/contract.md @@ -1,4 +1,6 @@ -# Contract -Approved API Design, represented by its API Description, **MUST** represent the **contract** between API stakeholder, implementers, and consumers. +# Contract + +Approved API Design, represented by its API Description or schema, **MUST** represent the **contract** between API stakeholder, implementers, and consumers. + +Any change to an API **MUST** be accompanied by a related update to the contract \(API Design\). -Any change to an API **MUST** be accompanied by a related update to the contract (API Description). diff --git a/core-principles/core-principles.md b/core-principles/core-principles.md new file mode 100644 index 0000000..e69de29 diff --git a/core-principles/introduction.md b/core-principles/introduction.md index e69de29..c640b9a 100644 --- a/core-principles/introduction.md +++ b/core-principles/introduction.md @@ -0,0 +1,38 @@ +# 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 General Guidelines. + +The REST API Guidelines are further split into the following parts: + +* **Core Principles** + + 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. + + * [**Message level**](https://adidas-group.gitbooks.io/api-guidelines/content/message/) + + The Message guidelines define the structure and semantics of messages used to exchange information. + + * [**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. + + * [**Evolution**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/) + + Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. + + * [**Execution**](https://adidas-group.gitbooks.io/api-guidelines/content/execution/) + + Execution qualities governance, such as security and usability. + + + diff --git a/core-principles/version-control-system.md b/core-principles/version-control-system.md index 78334f9..7bf6bbd 100644 --- a/core-principles/version-control-system.md +++ b/core-principles/version-control-system.md @@ -1,7 +1,4 @@ # Version Control System -Every API description **SHOULD** be stored in a Version Control System (Bitbucket, GitHub). Where possible the API description **SHOULD** stored in the **same** repository as the API implementation. - -> NOTE: The synchronization between the version control system and adidas [API Description platform](./apiary.md) - should be automated using CI/CD framework. +Every API design **SHOULD** be stored in a Version Control System \(Bitbucket, GitHub\). Where possible the API design **SHOULD** stored in the **same** repository as the API implementation. diff --git a/kafka/introduction.md b/kafka/introduction.md index 65a172c..7805b7d 100644 --- a/kafka/introduction.md +++ b/kafka/introduction.md @@ -1,2 +1,4 @@ -Apache Kafka at adidas +# adidas Kafka Guidelines + + From 777d42d90755fb2717965a5c59662bf8acd0df3e Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 12:23:03 +0000 Subject: [PATCH 06/17] Creates evolution/a.md Auto commit by GitBook Editor --- SUMMARY.md | 79 ++++++++++++++++++----------------- core-principles/functional.md | 0 evolution/a.md | 0 protocol/protocol.md | 0 4 files changed, 40 insertions(+), 39 deletions(-) create mode 100644 core-principles/functional.md create mode 100644 evolution/a.md create mode 100644 protocol/protocol.md diff --git a/SUMMARY.md b/SUMMARY.md index 7d9410f..79a094a 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -18,48 +18,49 @@ ## REST APIs * [Introduction](core-principles/introduction.md) -* [OpenAPI Specification](core-principles/openapi-specification.md) -* [API Design Platform](core-principles/apiary.md) -* [Design Maturity](core-principles/design-maturity.md) -* [Testing](core-principles/testing.md) -* [Protocol](protocol/README.md) - * [HTTP](protocol/http.md) - * [TLS](protocol/tls.md) - * [Separate Concerns](protocol/separate-concerns.md) - * [Request Methods](protocol/use-appropriate-methods.md) - * [Status Codes](protocol/use-appropriate-status-codes.md) -* [Message](message/README.md) - * [Message Formats](message/message-formats.md) - * [Content Negotiation](message/content-negotiation.md) - * [HAL](message/hal.md) - * [Problem Detail](message/error-reporting.md) - * [Foreign Key Relations](message/foreign-key-relations.md) -* [Application](application/README.md) - * [Corporate Data Model](application/harmonize-data.md) - * [Common Data Types](application/common-data-types.md) -* [Evolution](evolution/README.md) - * [Reserved Identifiers](evolution/reserved-identifiers.md) - * [Naming Conventions](evolution/naming-conventions.md) - * [Changes and Versioning](evolution/versioning.md) - * [URI Structure](evolution/uri-structure.md) - * [Testing Enviroments](execution/testing-enviroments.md) -* [Execution](execution/README.md) - * [Pagination](execution/pagination.md) - * [Asynchronous Tasks](execution/asynchronous-tasks.md) - * [Batch Operations](execution/batch-operations.md) - * [Search Requests](execution/search-requests.md) - * [Query Requests with Large Inputs](execution/query-requests-with-large-inputs.md) - * [Choosing Fields and Embedded Resources](execution/choosing-fields-and-embedded-resoruces.md) - * [Localization](execution/localization.md) - * [Rate Limiting](execution/rate-limiting.md) - * [Caching](execution/caching.md) +* [Core Principles](core-principles/core-principles.md) + * [OpenAPI Specification](core-principles/openapi-specification.md) + * [API Design Platform](core-principles/apiary.md) + * [Design Maturity](core-principles/design-maturity.md) + * [Testing](core-principles/testing.md) +* [Functionality](core-principles/functional.md) + * [Protocol](protocol/protocol.md) + * [HTTP](protocol/http.md) + * [TLS](protocol/tls.md) + * [Separate Concerns](protocol/separate-concerns.md) + * [Request Methods](protocol/use-appropriate-methods.md) + * [Status Codes](protocol/use-appropriate-status-codes.md) + * Message + * [Message Formats](message/message-formats.md) + * [Content Negotiation](message/content-negotiation.md) + * [HAL](message/hal.md) + * [Problem Detail](message/error-reporting.md) + * [Foreign Key Relations](message/foreign-key-relations.md) + * Application + * [Corporate Data Model](application/harmonize-data.md) + * [Common Data Types](application/common-data-types.md) +* Quality + * [Execution](execution/README.md) + * [Pagination](execution/pagination.md) + * [Asynchronous Tasks](execution/asynchronous-tasks.md) + * [Batch Operations](execution/batch-operations.md) + * [Search Requests](execution/search-requests.md) + * [Query Requests with Large Inputs](execution/query-requests-with-large-inputs.md) + * [Choosing Fields and Embedded Resources](execution/choosing-fields-and-embedded-resoruces.md) + * [Localization](execution/localization.md) + * [Rate Limiting](execution/rate-limiting.md) + * [Caching](execution/caching.md) + * [Evolution](evolution/README.md) + * [Naming Conventions](evolution/naming-conventions.md) + * [Reserved Identifiers](evolution/reserved-identifiers.md) + * [URI Structure](evolution/uri-structure.md) + * [Changes and Versioning](evolution/versioning.md) + * [Testing Enviroments](execution/testing-enviroments.md) + * [API Clients](clients/README.md) + * [Loose Coupling](clients/loose-coupling.md) * [Guides](guides/README.md) * [API Testing CI Environment](guides/api-testing-ci-environment.md) * [Complete API Development](guides/complete-api-development.md) -* [API Clients](clients/README.md) - * [Loose Coupling](clients/loose-coupling.md) -* [Examples](examples.md) -* Core Principles ## Kafka diff --git a/core-principles/functional.md b/core-principles/functional.md new file mode 100644 index 0000000..e69de29 diff --git a/evolution/a.md b/evolution/a.md new file mode 100644 index 0000000..e69de29 diff --git a/protocol/protocol.md b/protocol/protocol.md new file mode 100644 index 0000000..e69de29 From eb491f8cb4291a352cd6b75af1e628d8e2ddec32 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 12:28:48 +0000 Subject: [PATCH 07/17] Updates core-principles/introduction.md Auto commit by GitBook Editor --- SUMMARY.md | 8 ++++---- core-principles/introduction.md | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/SUMMARY.md b/SUMMARY.md index 79a094a..c882028 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -15,7 +15,7 @@ * [JSON](evolution/json.md) * [Security](execution/security.md) -## REST APIs +## REST API Guidelines * [Introduction](core-principles/introduction.md) * [Core Principles](core-principles/core-principles.md) @@ -56,13 +56,13 @@ * [URI Structure](evolution/uri-structure.md) * [Changes and Versioning](evolution/versioning.md) * [Testing Enviroments](execution/testing-enviroments.md) - * [API Clients](clients/README.md) - * [Loose Coupling](clients/loose-coupling.md) * [Guides](guides/README.md) * [API Testing CI Environment](guides/api-testing-ci-environment.md) * [Complete API Development](guides/complete-api-development.md) +* [API Clients](clients/README.md) + * [Loose Coupling](clients/loose-coupling.md) -## Kafka +## Kafka Guidelines * [Introduction](kafka/introduction.md) diff --git a/core-principles/introduction.md b/core-principles/introduction.md index c640b9a..deea0b3 100644 --- a/core-principles/introduction.md +++ b/core-principles/introduction.md @@ -34,5 +34,12 @@ 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 + +* **API Clients** + + Section dedicated to consumers of adidas APIs + From af1190a7611f639a711fce6f8bcad2ac8c578289 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 12:39:37 +0000 Subject: [PATCH 08/17] Deletes core-principles/functional.md Auto commit by GitBook Editor --- SUMMARY.md | 16 +-- core-principles/api-first.md | 10 -- core-principles/contract.md | 6 - core-principles/functional.md | 0 core-principles/minimal-api-surface.md | 2 - core-principles/rules-for-extending.md | 15 --- core-principles/version-control-system.md | 4 - evolution/a.md | 0 evolution/json.md | 9 -- execution/security.md | 115 ------------------ general-guidelines/README.md | 2 + general-guidelines/api-first.md | 10 ++ general-guidelines/contract.md | 6 + general-guidelines/json.md | 9 ++ general-guidelines/minimal-api-surface.md | 4 + .../robustness.md | 0 general-guidelines/rules-for-extending.md | 15 +++ general-guidelines/security.md | 115 ++++++++++++++++++ general-guidelines/version-control-system.md | 4 + miscellaneous.md | 7 +- 20 files changed, 178 insertions(+), 171 deletions(-) delete mode 100644 core-principles/functional.md delete mode 100644 core-principles/minimal-api-surface.md delete mode 100644 evolution/a.md create mode 100644 general-guidelines/README.md create mode 100644 general-guidelines/api-first.md create mode 100644 general-guidelines/contract.md create mode 100644 general-guidelines/json.md create mode 100644 general-guidelines/minimal-api-surface.md rename {core-principles => general-guidelines}/robustness.md (100%) create mode 100644 general-guidelines/rules-for-extending.md create mode 100644 general-guidelines/security.md create mode 100644 general-guidelines/version-control-system.md diff --git a/SUMMARY.md b/SUMMARY.md index c882028..2f81a61 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -6,14 +6,14 @@ ## General Guidelines -* [API First](core-principles/api-first.md) -* [Contract](core-principles/contract.md) -* [Version Control System](core-principles/version-control-system.md) -* [Robustness](core-principles/robustness.md) -* [Minimal API Surface](core-principles/minimal-api-surface.md) -* [Rules for Extending](core-principles/rules-for-extending.md) -* [JSON](evolution/json.md) -* [Security](execution/security.md) +* [API First](general-guidelines/api-first.md) +* [Contract](general-guidelines/contract.md) +* [Robustness](general-guidelines/robustness.md) +* [Version Control System](general-guidelines/version-control-system.md) +* [Minimal API Surface](general-guidelines/minimal-api-surface.md) +* [Rules for Extending](general-guidelines/rules-for-extending.md) +* [JSON](general-guidelines/json.md) +* [Security](general-guidelines/security.md) ## REST API Guidelines diff --git a/core-principles/api-first.md b/core-principles/api-first.md index 03a1353..e69de29 100644 --- a/core-principles/api-first.md +++ b/core-principles/api-first.md @@ -1,10 +0,0 @@ -# API First - -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 implementation **MUST** always be compliant to particular API design which represents the [contract](./contract.md) between API, and it's consumer. - diff --git a/core-principles/contract.md b/core-principles/contract.md index f960c23..e69de29 100644 --- a/core-principles/contract.md +++ b/core-principles/contract.md @@ -1,6 +0,0 @@ -# Contract - -Approved API Design, represented by its API Description or schema, **MUST** represent the **contract** between API stakeholder, implementers, and consumers. - -Any change to an API **MUST** be accompanied by a related update to the contract \(API Design\). - diff --git a/core-principles/functional.md b/core-principles/functional.md deleted file mode 100644 index e69de29..0000000 diff --git a/core-principles/minimal-api-surface.md b/core-principles/minimal-api-surface.md deleted file mode 100644 index 7c39b01..0000000 --- a/core-principles/minimal-api-surface.md +++ /dev/null @@ -1,2 +0,0 @@ -# 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)). \ No newline at end of file diff --git a/core-principles/rules-for-extending.md b/core-principles/rules-for-extending.md index c7e3c72..e69de29 100644 --- a/core-principles/rules-for-extending.md +++ b/core-principles/rules-for-extending.md @@ -1,15 +0,0 @@ -# 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)) -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. - - diff --git a/core-principles/version-control-system.md b/core-principles/version-control-system.md index 7bf6bbd..e69de29 100644 --- a/core-principles/version-control-system.md +++ b/core-principles/version-control-system.md @@ -1,4 +0,0 @@ -# Version Control System - -Every API design **SHOULD** be stored in a Version Control System \(Bitbucket, GitHub\). Where possible the API design **SHOULD** stored in the **same** repository as the API implementation. - diff --git a/evolution/a.md b/evolution/a.md deleted file mode 100644 index e69de29..0000000 diff --git a/evolution/json.md b/evolution/json.md index 0a1ca23..e69de29 100644 --- a/evolution/json.md +++ b/evolution/json.md @@ -1,9 +0,0 @@ -# JSON Format Conventions -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": []`) diff --git a/execution/security.md b/execution/security.md index 115e685..e69de29 100644 --- a/execution/security.md +++ b/execution/security.md @@ -1,115 +0,0 @@ -# API Authentication -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. - -## 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. - -## 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. -* 400 Bad Request - The request is malformed, such as message body format error. -* 401 Unauthorized - Wrong or no authentication ID/password provided. -* 403 Forbidden - It's used when the authentication succeeded but authenticated user doesn't have permission to the requested resource -* 404 Not Found - When a non-existent resource is requested -* 405 Method Not Allowed - The error checking for unexpected HTTP method. For example, the RestAPI is expecting HTTP GET, but HTTP PUT is used. -* 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. - -* 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 don’t want it to. Typically this means removing `// <![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 -* HTML5 Web Storage - -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 won’t 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]. - - -[preventxss]: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_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: - -* 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. - -## 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 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). -* 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 -* Server SHOULD be protected from CRIME attack, TLS compression MUST be disabled -* Server SHOULD support Forward Secrecy - -## Mixed Content -When serving up content to your users over SSL, it’s 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 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. -* 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. - -## 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. diff --git a/general-guidelines/README.md b/general-guidelines/README.md new file mode 100644 index 0000000..461b62a --- /dev/null +++ b/general-guidelines/README.md @@ -0,0 +1,2 @@ +General Guidelines + diff --git a/general-guidelines/api-first.md b/general-guidelines/api-first.md new file mode 100644 index 0000000..03a1353 --- /dev/null +++ b/general-guidelines/api-first.md @@ -0,0 +1,10 @@ +# API First + +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 implementation **MUST** always be compliant to particular API design which represents the [contract](./contract.md) between API, and it's consumer. + diff --git a/general-guidelines/contract.md b/general-guidelines/contract.md new file mode 100644 index 0000000..f960c23 --- /dev/null +++ b/general-guidelines/contract.md @@ -0,0 +1,6 @@ +# Contract + +Approved API Design, represented by its API Description or schema, **MUST** represent the **contract** between API stakeholder, implementers, and consumers. + +Any change to an API **MUST** be accompanied by a related update to the contract \(API Design\). + diff --git a/general-guidelines/json.md b/general-guidelines/json.md new file mode 100644 index 0000000..0a1ca23 --- /dev/null +++ b/general-guidelines/json.md @@ -0,0 +1,9 @@ +# JSON Format Conventions +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": []`) diff --git a/general-guidelines/minimal-api-surface.md b/general-guidelines/minimal-api-surface.md new file mode 100644 index 0000000..839675d --- /dev/null +++ b/general-guidelines/minimal-api-surface.md @@ -0,0 +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\)](https://martinfowler.com/bliki/Yagni.html%29\)\). + diff --git a/core-principles/robustness.md b/general-guidelines/robustness.md similarity index 100% rename from core-principles/robustness.md rename to general-guidelines/robustness.md diff --git a/general-guidelines/rules-for-extending.md b/general-guidelines/rules-for-extending.md new file mode 100644 index 0000000..c7e3c72 --- /dev/null +++ b/general-guidelines/rules-for-extending.md @@ -0,0 +1,15 @@ +# 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)) +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. + + diff --git a/general-guidelines/security.md b/general-guidelines/security.md new file mode 100644 index 0000000..115e685 --- /dev/null +++ b/general-guidelines/security.md @@ -0,0 +1,115 @@ +# API Authentication +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. + +## 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. + +## 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. +* 400 Bad Request - The request is malformed, such as message body format error. +* 401 Unauthorized - Wrong or no authentication ID/password provided. +* 403 Forbidden - It's used when the authentication succeeded but authenticated user doesn't have permission to the requested resource +* 404 Not Found - When a non-existent resource is requested +* 405 Method Not Allowed - The error checking for unexpected HTTP method. For example, the RestAPI is expecting HTTP GET, but HTTP PUT is used. +* 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. + +* 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 don’t want it to. Typically this means removing `// <![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 +* HTML5 Web Storage + +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 won’t 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]. + + +[preventxss]: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_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: + +* 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. + +## 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 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). +* 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 +* Server SHOULD be protected from CRIME attack, TLS compression MUST be disabled +* Server SHOULD support Forward Secrecy + +## Mixed Content +When serving up content to your users over SSL, it’s 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 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. +* 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. + +## 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. diff --git a/general-guidelines/version-control-system.md b/general-guidelines/version-control-system.md new file mode 100644 index 0000000..7bf6bbd --- /dev/null +++ b/general-guidelines/version-control-system.md @@ -0,0 +1,4 @@ +# Version Control System + +Every API design **SHOULD** be stored in a Version Control System \(Bitbucket, GitHub\). Where possible the API design **SHOULD** stored in the **same** repository as the API implementation. + diff --git a/miscellaneous.md b/miscellaneous.md index 8db1862..512f5bb 100644 --- a/miscellaneous.md +++ b/miscellaneous.md @@ -1,4 +1,7 @@ # Miscellaneous -- [Product tokens](https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-16#section-6.3) -- [Deprecating "X-"](https://tools.ietf.org/html/rfc6648) \ No newline at end of file +* [Product tokens](https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-16#section-6.3) +* [Deprecating "X-"](https://tools.ietf.org/html/rfc6648) + + + From 6ae3093b2224b4259ceb44d2609399d53596bd86 Mon Sep 17 00:00:00 2001 From: Z Date: Sat, 23 Jun 2018 14:40:10 +0200 Subject: [PATCH 09/17] Fix markdown escaping --- general-guidelines/minimal-api-surface.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/general-guidelines/minimal-api-surface.md b/general-guidelines/minimal-api-surface.md index 839675d..507ace1 100644 --- a/general-guidelines/minimal-api-surface.md +++ b/general-guidelines/minimal-api-surface.md @@ -1,4 +1,2 @@ -\# 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\)](https://martinfowler.com/bliki/Yagni.html%29\)\). - +# 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)). From 958d90ea5d5781d4b7516b59e7611c1a1b6f5b10 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 12:56:08 +0000 Subject: [PATCH 10/17] Creates rest/core-principles/quality.md Auto commit by GitBook Editor --- SUMMARY.md | 86 ++++++------- application/common-data-types.md | 37 ------ core-principles/apiary.md | 16 --- core-principles/design-maturity.md | 16 --- .../{api-first.md => functional.md} | 0 core-principles/introduction.md | 45 ------- core-principles/openapi-specification.md | 7 - core-principles/testing.md | 4 - evolution/naming-conventions.md | 117 ----------------- evolution/uri-structure.md | 8 -- evolution/versioning.md | 102 --------------- execution/README.md | 2 - execution/asynchronous-tasks.md | 26 ---- execution/caching.md | 45 ------- .../choosing-fields-and-embedded-resoruces.md | 80 ------------ execution/localization.md | 37 ------ execution/pagination.md | 27 ---- execution/query-requests-with-large-inputs.md | 17 --- execution/rate-limiting.md | 63 --------- execution/testing-enviroments.md | 3 - guides/README.md | 9 -- guides/api-testing-ci-environment.md | 101 --------------- message/content-negotiation.md | 28 ---- message/error-reporting.md | 120 ------------------ message/foreign-key-relations.md | 67 ---------- message/hal.md | 114 ----------------- protocol/separate-concerns.md | 49 ------- protocol/tls.md | 4 - protocol/use-appropriate-methods.md | 45 ------- protocol/use-appropriate-status-codes.md | 44 ------- core-principles/contract.md => rest/README.md | 0 {application => rest/application}/README.md | 0 rest/application/common-data-types.md | 37 ++++++ .../application}/harmonize-data.md | 0 {clients => rest/clients}/README.md | 0 {clients => rest/clients}/loose-coupling.md | 0 .../core-principles}/README.md | 0 .../core-principles/api-first.md | 0 rest/core-principles/apiary.md | 16 +++ .../core-principles/contract.md | 0 .../core-principles/core-principles.md | 0 rest/core-principles/design-maturity.md | 16 +++ rest/core-principles/introduction.md | 45 +++++++ rest/core-principles/openapi-specification.md | 7 + .../core-principles/quality.md | 0 rest/core-principles/testing.md | 4 + .../core-principles/version-control-system.md | 0 {evolution => rest/evolution}/README.md | 0 rest/evolution/json.md | 0 rest/evolution/naming-conventions.md | 117 +++++++++++++++++ .../evolution}/reserved-identifiers.md | 0 rest/evolution/uri-structure.md | 8 ++ rest/evolution/versioning.md | 102 +++++++++++++++ examples.md => rest/examples.md | 0 rest/execution/README.md | 2 + {execution => rest/execution}/api-keys.md | 0 rest/execution/asynchronous-tasks.md | 26 ++++ .../execution}/authentication.md | 0 .../execution}/batch-operations.md | 0 rest/execution/caching.md | 45 +++++++ .../choosing-fields-and-embedded-resoruces.md | 80 ++++++++++++ rest/execution/localization.md | 37 ++++++ rest/execution/pagination.md | 27 ++++ .../query-requests-with-large-inputs.md | 17 +++ rest/execution/rate-limiting.md | 63 +++++++++ .../execution}/search-requests.md | 0 rest/execution/security.md | 0 rest/execution/testing-enviroments.md | 3 + rest/guides/README.md | 9 ++ rest/guides/api-testing-ci-environment.md | 101 +++++++++++++++ .../guides}/complete-api-development.md | 0 {message => rest/message}/README.md | 0 rest/message/content-negotiation.md | 28 ++++ rest/message/error-reporting.md | 120 ++++++++++++++++++ rest/message/foreign-key-relations.md | 67 ++++++++++ rest/message/hal.md | 114 +++++++++++++++++ {message => rest/message}/message-formats.md | 0 miscellaneous.md => rest/miscellaneous.md | 0 {protocol => rest/protocol}/README.md | 0 {protocol => rest/protocol}/http.md | 0 {protocol => rest/protocol}/know-your-http.md | 0 rest/protocol/message.md | 0 rest/protocol/protocol.md | 0 rest/protocol/separate-concerns.md | 49 +++++++ rest/protocol/tls.md | 4 + rest/protocol/use-appropriate-methods.md | 45 +++++++ rest/protocol/use-appropriate-status-codes.md | 44 +++++++ 87 files changed, 1276 insertions(+), 1276 deletions(-) rename core-principles/{api-first.md => functional.md} (100%) rename core-principles/contract.md => rest/README.md (100%) rename {application => rest/application}/README.md (100%) create mode 100644 rest/application/common-data-types.md rename {application => rest/application}/harmonize-data.md (100%) rename {clients => rest/clients}/README.md (100%) rename {clients => rest/clients}/loose-coupling.md (100%) rename {core-principles => rest/core-principles}/README.md (100%) rename core-principles/rules-for-extending.md => rest/core-principles/api-first.md (100%) create mode 100644 rest/core-principles/apiary.md rename core-principles/version-control-system.md => rest/core-principles/contract.md (100%) rename evolution/json.md => rest/core-principles/core-principles.md (100%) create mode 100644 rest/core-principles/design-maturity.md create mode 100644 rest/core-principles/introduction.md create mode 100644 rest/core-principles/openapi-specification.md rename execution/security.md => rest/core-principles/quality.md (100%) create mode 100644 rest/core-principles/testing.md create mode 100644 rest/core-principles/version-control-system.md rename {evolution => rest/evolution}/README.md (100%) create mode 100644 rest/evolution/json.md create mode 100644 rest/evolution/naming-conventions.md rename {evolution => rest/evolution}/reserved-identifiers.md (100%) create mode 100644 rest/evolution/uri-structure.md create mode 100644 rest/evolution/versioning.md rename examples.md => rest/examples.md (100%) create mode 100644 rest/execution/README.md rename {execution => rest/execution}/api-keys.md (100%) create mode 100644 rest/execution/asynchronous-tasks.md rename {execution => rest/execution}/authentication.md (100%) rename {execution => rest/execution}/batch-operations.md (100%) create mode 100644 rest/execution/caching.md create mode 100644 rest/execution/choosing-fields-and-embedded-resoruces.md create mode 100644 rest/execution/localization.md create mode 100644 rest/execution/pagination.md create mode 100644 rest/execution/query-requests-with-large-inputs.md create mode 100644 rest/execution/rate-limiting.md rename {execution => rest/execution}/search-requests.md (100%) create mode 100644 rest/execution/security.md create mode 100644 rest/execution/testing-enviroments.md create mode 100644 rest/guides/README.md create mode 100644 rest/guides/api-testing-ci-environment.md rename {guides => rest/guides}/complete-api-development.md (100%) rename {message => rest/message}/README.md (100%) create mode 100644 rest/message/content-negotiation.md create mode 100644 rest/message/error-reporting.md create mode 100644 rest/message/foreign-key-relations.md create mode 100644 rest/message/hal.md rename {message => rest/message}/message-formats.md (100%) rename miscellaneous.md => rest/miscellaneous.md (100%) rename {protocol => rest/protocol}/README.md (100%) rename {protocol => rest/protocol}/http.md (100%) rename {protocol => rest/protocol}/know-your-http.md (100%) create mode 100644 rest/protocol/message.md create mode 100644 rest/protocol/protocol.md create mode 100644 rest/protocol/separate-concerns.md create mode 100644 rest/protocol/tls.md create mode 100644 rest/protocol/use-appropriate-methods.md create mode 100644 rest/protocol/use-appropriate-status-codes.md diff --git a/SUMMARY.md b/SUMMARY.md index 2f81a61..eb3f93c 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -17,50 +17,50 @@ ## REST API Guidelines -* [Introduction](core-principles/introduction.md) -* [Core Principles](core-principles/core-principles.md) - * [OpenAPI Specification](core-principles/openapi-specification.md) - * [API Design Platform](core-principles/apiary.md) - * [Design Maturity](core-principles/design-maturity.md) - * [Testing](core-principles/testing.md) +* [Introduction](rest/core-principles/introduction.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](protocol/protocol.md) - * [HTTP](protocol/http.md) - * [TLS](protocol/tls.md) - * [Separate Concerns](protocol/separate-concerns.md) - * [Request Methods](protocol/use-appropriate-methods.md) - * [Status Codes](protocol/use-appropriate-status-codes.md) - * Message - * [Message Formats](message/message-formats.md) - * [Content Negotiation](message/content-negotiation.md) - * [HAL](message/hal.md) - * [Problem Detail](message/error-reporting.md) - * [Foreign Key Relations](message/foreign-key-relations.md) - * Application - * [Corporate Data Model](application/harmonize-data.md) - * [Common Data Types](application/common-data-types.md) -* Quality - * [Execution](execution/README.md) - * [Pagination](execution/pagination.md) - * [Asynchronous Tasks](execution/asynchronous-tasks.md) - * [Batch Operations](execution/batch-operations.md) - * [Search Requests](execution/search-requests.md) - * [Query Requests with Large Inputs](execution/query-requests-with-large-inputs.md) - * [Choosing Fields and Embedded Resources](execution/choosing-fields-and-embedded-resoruces.md) - * [Localization](execution/localization.md) - * [Rate Limiting](execution/rate-limiting.md) - * [Caching](execution/caching.md) - * [Evolution](evolution/README.md) - * [Naming Conventions](evolution/naming-conventions.md) - * [Reserved Identifiers](evolution/reserved-identifiers.md) - * [URI Structure](evolution/uri-structure.md) - * [Changes and Versioning](evolution/versioning.md) - * [Testing Enviroments](execution/testing-enviroments.md) -* [Guides](guides/README.md) - * [API Testing CI Environment](guides/api-testing-ci-environment.md) - * [Complete API Development](guides/complete-api-development.md) -* [API Clients](clients/README.md) - * [Loose Coupling](clients/loose-coupling.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) ## Kafka Guidelines diff --git a/application/common-data-types.md b/application/common-data-types.md index a00d03d..e69de29 100644 --- a/application/common-data-types.md +++ b/application/common-data-types.md @@ -1,37 +0,0 @@ -# Common Data Types - -## Date and Time Format -Date and Time **MUST** always conform to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format e.g.: `2017-06-21T14:07:17Z` (date time) or `2017-06-21` (date), it **MUST** use the UTC (without time offsets). - -## Duration Format -Duration format **MUST** conform to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard e.g.: `P3Y6M4DT12H30M5S` (three years, six months, four days, twelve hours, thirty minutes, and five seconds). - -## Time Interval Format -Time Interval format **MUST** conform to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard e.g.: `2007-03-01T13:00:00Z/2008-05-11T15:30:00Z`. - -## Standard Time Stamps -Where applicable, a resource representation **SHOULD** contain the standard timestamps: - -- `createdAt` -- `updatedAt` -- `finishedAt` - -#### Example - -```json -{ - "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. diff --git a/core-principles/apiary.md b/core-principles/apiary.md index aa4985e..e69de29 100644 --- a/core-principles/apiary.md +++ b/core-principles/apiary.md @@ -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. - - - diff --git a/core-principles/design-maturity.md b/core-principles/design-maturity.md index 5ed72de..e69de29 100644 --- a/core-principles/design-maturity.md +++ b/core-principles/design-maturity.md @@ -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)). diff --git a/core-principles/api-first.md b/core-principles/functional.md similarity index 100% rename from core-principles/api-first.md rename to core-principles/functional.md diff --git a/core-principles/introduction.md b/core-principles/introduction.md index deea0b3..e69de29 100644 --- a/core-principles/introduction.md +++ b/core-principles/introduction.md @@ -1,45 +0,0 @@ -# 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 General Guidelines. - -The REST API Guidelines are further split into the following parts: - -* **Core Principles** - - 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. - - * [**Message level**](https://adidas-group.gitbooks.io/api-guidelines/content/message/) - - The Message guidelines define the structure and semantics of messages used to exchange information. - - * [**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. - - * [**Evolution**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/) - - Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. - - * [**Execution**](https://adidas-group.gitbooks.io/api-guidelines/content/execution/) - - Execution qualities governance, such as security and usability. - -* **Guides** - Guides and materials supporting the REST API Guidelines - -* **API Clients** - - Section dedicated to consumers of adidas APIs - - - diff --git a/core-principles/openapi-specification.md b/core-principles/openapi-specification.md index c54f215..e69de29 100644 --- a/core-principles/openapi-specification.md +++ b/core-principles/openapi-specification.md @@ -1,7 +0,0 @@ -# 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. - -## Language -The API description MUST be written in **American English**. diff --git a/core-principles/testing.md b/core-principles/testing.md index 9a8ca38..e69de29 100644 --- a/core-principles/testing.md +++ b/core-principles/testing.md @@ -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. diff --git a/evolution/naming-conventions.md b/evolution/naming-conventions.md index 8e25cf0..e69de29 100644 --- a/evolution/naming-conventions.md +++ b/evolution/naming-conventions.md @@ -1,117 +0,0 @@ -# Naming Conventions - -## General Naming Rules - -- Use American English -- Don't use acronyms -- Use `camelCase` unless stated otherwise -- Reconcile terms with adidas CDM - -Every identifier **MUST** be in American English and written in `lowercase`. An identifier **SHOULD NOT** contain acronyms. CamelCase (`camelCase`) **MUST** be used to delimit combined words. - -## URI -Every URI **MUST** follow the General Rules except for the `camelCase` rule. Instead, a hyphen (`-`) **SHOULD** be used to delimit combined words (kebab-case). Besides, a URI **MUST NOT** end with a trailing slash (`/`). - -#### Example -A well-formed URI: - -``` -/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. - -#### Example -A well-formed URI Template Variable: - -``` -/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 -{ - "_links": { - "self": { - "href": "/orders/1234" - }, - "author": { - "href": "/users/john" - } - }, - "orderNumber": 1234, - "itemCount": 42, - "status": "pending" -} -``` - -## Relation Type Identifier -Every custom [relation identifier](https://github.com/for-GET/know-your-http-well/blob/master/relations.md) **MUST** be in `lowercase` with words separated by the hyphen (`-`). - -#### Example -A well-formed resource representation with custom relation `fulfillment-provider`: - -```json -{ - "_links": { - "fulfillment-provider": { - "href": "/users/natalie" - } - } -} -``` - - -## HTTP Headers -Every HTTP Header should use `Hyphenated-Pascal-Case`. A custom HTTP Header **SHOULD NOT** start with `X-` ([RFC6648](https://tools.ietf.org/html/rfc6648)). - -#### Example - -``` -Order-Metadata-Header: 42 -``` - - -## API Description -Naming conventions within API Description document. - -### API Name -Every API Description API name **MUST** start with API domain enclosed in square brackets (e.g. `[API Domain] My API`). Words **MUST** be separated by space. - -#### Example - -```yaml -swagger: '2.0' -info: - version: '1.0.0' - title: '[Demo] Orders API' -``` - -### Resource Name -Every resource **MUST** have a name (defined by `x-summary` field). Resource name **MUST** be in `Title Case`. Words **MUST** be separated by a space. - -#### Example -```yaml -/orders: - x-summary: List of Orders -``` - -### Action Name -Every action (operation) **MUST** have a name (defined by `summary` field). Action name **MUST** be in `Title Case`. Words **MUST** be separated by a space. - -#### Example -```yaml -get: - summary: Retrieve List of Orders -``` diff --git a/evolution/uri-structure.md b/evolution/uri-structure.md index a9ecbcd..e69de29 100644 --- a/evolution/uri-structure.md +++ b/evolution/uri-structure.md @@ -1,8 +0,0 @@ -# URI Design -URI is meant to express a **identity of a resource**. URI is an identifier and it **MUST NOT** convey any other information. - -The API design process **MUST NOT** start with the design of URIs. Contrary, the URI **SHOULD** be amongst the last few things added to the API design. - -At adidas, URIs are subject to [naming conventions](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). diff --git a/evolution/versioning.md b/evolution/versioning.md index a45eedc..e69de29 100644 --- a/evolution/versioning.md +++ b/evolution/versioning.md @@ -1,102 +0,0 @@ -# Changes and Versioning - -> _The fundamental principle is that you can’t break existing clients, because you don’t know what they implement, and you don’t control them. In doing so, you need to turn a backwards-incompatible change into a compatible one._ -> -> _– _[_Mark Nottingham_](https://www.mnot.net/blog/2011/10/25/web_api_versioning_smackdown) - -Any change to an API **MUST NOT** break existing clients. - -Any change to: -1. **Resource identifier** \(resource name / URI\) including any **query parameters** and their semantics -1. **Resource metadata** \(e.g. HTTP headers\) -1. **Action** the resource affords \(e.g. available HTTP Methods\) -1. **Relation** with other resources \(e.g Links\) -1. **Representation format** \(e.g. HTTP request and response bodies\) - -**MUST** follow the [**Rules for Extending**](https://adidas-group.gitbooks.io/api-guidelines/content/core-principles/rules-for-extending.html). - -## Identifier Stability \(No URI Versioning\) - -A change **MUST NOT** affect **existing** resource identifiers \(name / URI\). Furthermore, a resource identifier **MUST NOT** contain a semantic version to convey a version of resource or its representation format. - -> _The reason to make a real REST API is to get evolvability … a "v1" is a .... to your API customers, indicating RPC/HTTP \(not REST\)_ -> -> _– _[_Roy T. Fielding_](https://twitter.com/fielding/status/376835835670167552) - -#### Example - -Adding a new action to existing resource with identifier `/greeting` doesn't change its identifier to `/v2/greeting` \(or `/greeting-with-new-action` etc.\). - -## Backward-incompatible Changes - -A change to _resource identifier_, _resource metadata_, _resource actions_ and _resource relations_ that can't follow the [Rules for Extending](https://adidas-group.gitbooks.io/api-guidelines/content/core-principles/rules-for-extending.html) **MUST** result into a **new resource variant**. Existing resource variant **MUST** be preserved. - -A change to _representation format_ **SHOULD NOT** result into a new resource variant. - -#### Example - -Currently, optional URI Query Parameter `first` on an existing resource `/greeting?first=John&last=Appleseed` needs to be made required. Since this change violates the 3rd rule of extending and could break existing clients a new variant of the resource is created with different URI `/named-greeting?first=John&last=Appleseed`. - -### Representation Format Changes - -> A representation format is the serialization format \(media type\) used in request and response bodies, and typically it represents a resource or its part, possibly with additional hypermedia controls. - -If a change can't follow the Rules for Extending the representation format media type **MUST** be changed. If the media type has been changed the previous media type, **MUST** be available via [Content Negotiation](https://adidas-group.gitbooks.io/api-guidelines/content/message/content-negotiation.html). - -If the media type conveys the version parameter, the version parameter **SHOULD** follow [Semantic versioning](http://semver.org/). - -#### Example - -Media type _before_ a breaking change: - -``` -application/vnd.example.resource+json; version=2 -``` - -Media type _after_ a breaking change: - -``` -application/vnd.example.resource+json; version=3 -``` - -> NOTE: In the case of technical limitations with semi-colon separated HTTP header values, the semantic version MAY be incorporated in the media type identifier, for example: `application/vnd.example.resource.v2+json` However, the use of semicolon-separated version information is preferred. - -## API Description Versioning - -API Description in the OpenAPI specification format **MUST** have the `version` field. The `version` field **MUST** follow [Semantic versioning](http://semver.org/): - -> Given a version number MAJOR.MINOR.PATCH, increment the: -> -> * MAJOR version when you make **incompatible** API changes, -> * MINOR version when you add functionality in a **backwards-compatible** manner -> * PATCH version when you make **backwards-compatible bug fixes** - -The API Description version **SHOULD** be updated accordingly to API design change. - -#### Example - -Following API Description - -```yaml -swagger: '2.0' -info: - version: '2.1.3' - title: '[Demo] Inventory API' - description: 'Inventory service API' -``` - -Has MAJOR version 2, MINOR version 1 and PATCH version 3. - -#### Demo - -API description \(OAS2\) files demonstrating a proposal of an backward-incompatible change turned into a backward compatible change are available at [Bitbucket \(diff\) ](https://bitbucket.org/apidesigner/demo-versioning-api/pull-requests/1/add-name-parameter/diff)and documented in Apiary: - -* [Production version](https://demoversioningproduction.docs.apiary.io/#) as being consumed by clients -* [Development version](https://demoversioningdevelopment.docs.apiary.io/#) proposing a backward incompatible change - -#### Recommended Reading - -* [Evolving HTTP APIs](https://www.mnot.net/blog/2012/12/04/api-evolution) - - - diff --git a/execution/README.md b/execution/README.md index 3477681..e69de29 100644 --- a/execution/README.md +++ b/execution/README.md @@ -1,2 +0,0 @@ -# Execution -Performance qualities, such as security and usability, which are observable at run time. diff --git a/execution/asynchronous-tasks.md b/execution/asynchronous-tasks.md index 2c61486..e69de29 100644 --- a/execution/asynchronous-tasks.md +++ b/execution/asynchronous-tasks.md @@ -1,26 +0,0 @@ -# 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. - -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. - -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. - -3. Task 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. - diff --git a/execution/caching.md b/execution/caching.md index 1fe746d..e69de29 100644 --- a/execution/caching.md +++ b/execution/caching.md @@ -1,45 +0,0 @@ -# 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)). - -## 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. - - -### 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. - -#### 1. Cache Expiration & Revalidation -The common scenario to set cache expiration and revalidation policy is to use the `max-age` and `must-revalidate` directives: - -``` -HTTP/1.1 200 OK -Date: Mon, 19 Aug 2017 00:00:00 CEST -Last-Modified: Mon, 19 Aug 2017 00:00:00 CEST -Cache-Control: max-age=3600,must-revalidate -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: - -``` -HTTP/1.1 200 OK -Date: Mon, 19 Aug 2017 00:00:00 CEST -Last-Modified: Mon, 19 Aug 2017 00:00:00 CEST -Cache-Control: no-cache, no-store, must-revalidate -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. diff --git a/execution/choosing-fields-and-embedded-resoruces.md b/execution/choosing-fields-and-embedded-resoruces.md index 515738c..e69de29 100644 --- a/execution/choosing-fields-and-embedded-resoruces.md +++ b/execution/choosing-fields-and-embedded-resoruces.md @@ -1,80 +0,0 @@ -# Choosing Fields & 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`). - -#### Example -Retrieve only some details of an Order resource: - -HTTP Request -``` -GET /order/1234?fields=_links,orderNumber,status HTTP/1.1 -Accept: application/hal+json -``` - -HTTP Response -``` -HTTP/1.1 200 OK -Content-Type: application/hal+json - -{ - "_links": { - "self": { "href": "/orders/1234" }, - "author": { "href": "/users/john" }, - "items": [ ... ] - }, - "orderNumber": 1234, - "status": "pending" -} -``` - -## 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. - - -#### Example -Embed only information about the Author of an Order resource. We are not interested in Items that are in this order. - -HTTP Request - -``` -GET /order/1234?embed=author HTTP/1.1 -Accept: application/hal+json -``` - -HTTP Response -``` -HTTP/1.1 200 OK -Content-Type: application/hal+json - -{ - "_links": { - "self": { "href": "/orders/1234" }, - "author": { "href": "/users/john" }, - "items": [ ... ] - }, - "orderNumber": 1234, - "itemCount": 42, - "status": "pending", - "_embedded": { - "author": { - "_links": { "self": "/users/john" }, - "name": "John Appleseed", - "email": "john@apple.com" - } - } -} -``` - -## 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. diff --git a/execution/localization.md b/execution/localization.md index eb96e61..e69de29 100644 --- a/execution/localization.md +++ b/execution/localization.md @@ -1,37 +0,0 @@ -# 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 - -``` -GET /article HTTP/1.1 -Accept-Language: en,en-US,fr;q=0.6 -``` - -``` -HTTP/1.1 200 OK -Content-Type: application/hal+json;charset=UTF-8 -Content-Language: en -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 - -``` -GET /article?market=en_US HTTP/1.1 -``` -``` -HTTP/1.1 200 OK -Content-Type: application/hal+json;charset=UTF-8 -Content-Language: en -Vary: Accept-Language - -... -``` diff --git a/execution/pagination.md b/execution/pagination.md index fc4a22c..e69de29 100644 --- a/execution/pagination.md +++ b/execution/pagination.md @@ -1,27 +0,0 @@ -# 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 -The Collection of Orders using the collection navigation link and `offset` and `limit` query parameters: - - -```json -{ - "_links": { - "self": { "href": "/orders?offset=100&limit=10" }, - "prev": { "href": "/orders?offset=90&limit=10" }, - "next": { "href": "/orders?offset=110&limit=10" }, - "first": { "href": "/orders?limit=10" }, - "last": { "href": "/orders?offset=900&limit=10" } - }, - "total_count": 910, - "_embedded": { - "order": [ - { ... }, - { ... }, - - ... - ] - } -} -``` diff --git a/execution/query-requests-with-large-inputs.md b/execution/query-requests-with-large-inputs.md index 6d6bb87..e69de29 100644 --- a/execution/query-requests-with-large-inputs.md +++ b/execution/query-requests-with-large-inputs.md @@ -1,17 +0,0 @@ -# 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). - -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 - -``` -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._ diff --git a/execution/rate-limiting.md b/execution/rate-limiting.md index 3d96593..e69de29 100644 --- a/execution/rate-limiting.md +++ b/execution/rate-limiting.md @@ -1,63 +0,0 @@ -# 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. - -## 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: - -``` -HTTP/1.1 403 Forbidden -Content-Type: application/problem+json - -X-Error-Detail-Header: Account Over Rate Limit -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 -Example response to a request over the throttle limit: - -``` -HTTP/1.1 403 Forbidden -Content-Type: application/problem+json - -Retry-After: 1 -X-Error-Detail-Header: Account Over Queries Per Second Limit -X-Mashery-Error-Code: ERR_403_DEVELOPER_OVER_QPS - -{ - "title": "Quota Limit Exceeded", - "detail": "Account Over Queries Per Second Limit" -} -``` - -> 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: - -``` -HTTP/1.1 200 OK - -X-Plan-QPS-Allotted: 10 -X-Plan-QPS-Current: 1 -X-Plan-Quota-Allotted: 1000 -X-Plan-Quota-Current: 2 -X-Plan-Quota-Reset: Tuesday, June 6, 2017 12:00:00 AM GMT -``` diff --git a/execution/testing-enviroments.md b/execution/testing-enviroments.md index f51c49a..e69de29 100644 --- a/execution/testing-enviroments.md +++ b/execution/testing-enviroments.md @@ -1,3 +0,0 @@ -# Testing Environments -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. - diff --git a/guides/README.md b/guides/README.md index bf7dfc5..e69de29 100644 --- a/guides/README.md +++ b/guides/README.md @@ -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 \ No newline at end of file diff --git a/guides/api-testing-ci-environment.md b/guides/api-testing-ci-environment.md index 49fd22e..e69de29 100644 --- a/guides/api-testing-ci-environment.md +++ b/guides/api-testing-ci-environment.md @@ -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 (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. diff --git a/message/content-negotiation.md b/message/content-negotiation.md index bd71338..e69de29 100644 --- a/message/content-negotiation.md +++ b/message/content-negotiation.md @@ -1,28 +0,0 @@ - -# 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: - -``` -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: - -``` -HTTP/1.1 200 OK -Content-Type: application/vnd.example.resource+json; version=2.1.3 -... -``` - -> NOTE: A server that doesn't have the requested representation media type available MUST respond with the HTTP Status Code **406 Not Acceptable**. -> -> NOTE: A server MAY have multiple choices available and MAY respond with the **300 Multiple Choices** response. In which case client SHOULD choose from the presented choices. -> -> You can read more about content negotiation at [MDN Content negotiation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation). diff --git a/message/error-reporting.md b/message/error-reporting.md index d43451b..e69de29 100644 --- a/message/error-reporting.md +++ b/message/error-reporting.md @@ -1,120 +0,0 @@ -# Problem Detail -The [`application/problem+json`](https://tools.ietf.org/html/rfc7807) (Problem Detail) **MUST** be used to communicate details about an error. - -Problem Detail is intended for use with the HTTP status codes 4xx and 5xx. Problem Detail **MUST NOT** be used with 2xx status code responses. - -At the minimum, any Problem Detail response **MUST** have the `title` and `detail` fields. - -#### Example - -```json -{ - "title": "Authentication required", - "detail": "Missing authentication credentials for the Greeting resource." -} -``` - -## Optional Fields -It **SHOULD** has the `type` field with the identifier of the error, besides it **MAY** have the `instance` field with the URI of the resource in question. If the Problem Detail response has the `status` field it **MUST** have the same value as HTTP Status code from of the response. - - -```json -{ - "type": "https://adidas-group.com/problems/scv/unauthorized", - "title": "Authentication required", - "detail": "Missing authentication credentials for the Greeting resource.", - "instance": "/greeting", - "status": 401 -} -``` - -> NOTE: The `type` field is an identifier, and as such it **MAY** be used to denote additional error codes. Keep in mind that the identifier should be a URI. - -## Additional Fields -If needed, the Problem Detail **MAY** include additional fields, refer to [RFC7807](https://tools.ietf.org/html/rfc7807) for details. - -## Validation Errors -When necessary, a Problem Detail response **MAY** include additional error details about the problems that have occurred. - -These additional errors **MUST** be under the `errors` and **MUST** follow the Problem Detail structure. - -#### Example - -Request: - -``` -POST /my-resource HTTP/1.1 -Content-Type: application/json - -{ - "age": -32, - "color": "cyan" -} -``` - -Response: - -``` -HTTP/1.1 400 Bad Request -Content-Type: application/problem+json -Content-Language: en - -{ - "type": "https://example.net/validation_error", - "title": "Your request parameters didn't validate.", - "instance": "/my-resource", - "status": 400, - - "errors": [ - { - "type": "https://example.net/invalid_params", - "instance": "/age", - "title": "Invalid Parameter", - "detail": "age must be a positive integer" - }, - { - "type": "https://example.net/invalid_params", - "instance": "/color", - "title": "Invalid Parameter", - "detail": "color must be 'green', 'red' or 'blue'" - } - ] -} -``` - - - -## Problem Detail and Content Negotiation -#### Example -A request is made to retrieve a resource representation: - -``` -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: - -``` -HTTP/1.1 401 Unauthorized -Content-Type: application/problem+json -Content-Language: en - -{ - "type": "https://adidas-group.com/problems/scv/unauthorized", - "title": "Authentication required", - "detail": "Missing authentication credentials for the Greeting resource.", - "instance": "/greeting", - "status": 401 -} -``` - -## No Stack Traces or Server Logs -> _Problem details are not a debugging tool for the underlying implementation; rather, they are a way to expose greater detail about the HTTP interface itself._ -> -> _– [RFC7807](https://tools.ietf.org/html/rfc7807)_ - -A Problem Detail response **MUST NOT** contain a program stack trace or server log for debugging purposes. Instead, provide a `logref` field with reference to the particular server log. - -## Working with Problem Detail -There are a whole plethora of libraries working with Problem Detail, for example, see [Zalando / Problem](https://github.com/zalando/problem) (Java). diff --git a/message/foreign-key-relations.md b/message/foreign-key-relations.md index 6df2fe3..e69de29 100644 --- a/message/foreign-key-relations.md +++ b/message/foreign-key-relations.md @@ -1,67 +0,0 @@ -# Foreign Key Relations - -## Link or Embed Foreign Key Relation -When a resource representation includes relation with another (foreign) resource, the relation **MUST** be expressed as a link relation or embed the related resource. - -#### Example -Use: - -```json -{ - "_links": { - "author": { "href": "/users/john" } - ... - } - ... -} -``` - -or: - -```json -{ - ... - "_embedded": { - "author": { - "_links": { "self": "/users/john" }, - "name": "John Appleseed", - "email": "john@apple.com" - } - } -} -``` - -instead: - -```json -{ - ... - "authorHref": "/users/john" -} -``` - -## Nest Foreign Key Relation -If a foreign object has another identifier, but URI or the foreign object isn't a resource, the object **MUST** be nested. - -#### Example -Use: - -```json -{ - "author": { - "id": "1234", - "name": "John Appleseed", - "email": "john@apple.com" - } -} -``` - -instead: - -```json -{ - "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. diff --git a/message/hal.md b/message/hal.md index 553eb7d..e69de29 100644 --- a/message/hal.md +++ b/message/hal.md @@ -1,114 +0,0 @@ -# HAL -The [`application/hal+json`](http://stateless.co/hal_specification.html) (HAL) **MUST** be used as the representation format of a resource. - -## Introduction to HAL -> _HAL is a simple format that gives a consistent and easy way to hyperlink between resources in your API._ - -This document is an informal introduction to the HAL media type. For more details see [HAL - Hypertext Application Language Specification](http://stateless.co/hal_specification.html). - -## Simple Document Example -The simplest Hal document looks like an empty JSON (it is an empty JSON!): - -```json -{ -} -``` - -A document representing a "Greeting" resource might look like: - -```json -{ - "message": "Hello World!", - "_links": { - "self": { - "href": "/greeting" - } - } -} -``` -The field `_links` has a special meaning in HAL. It denotes a list of link relations - a pair of a relation identifier and a link (URI). - -These link relations are used to express the relation of a resource with other resources. - -In our case the "Greeting" resource isn't related to other resources but itself, hence the `self` relation pointing to the Greeting resource. - -> NOTE: It is **customary** for every resource representation to include the `self` link relation. - -> NOTE: The href **MUST** always be **relative path to the API root** (e.g. without the host and scheme). - -## Relation Example -A more complex document example could be an "Order" resource that has a related resource "Author" (a person who created the order. It might look like: - -```json -{ - "_links": { - "self": { - "href": "/orders/1234" - }, - "author": { - "href": "/users/john" - } - }, - "orderNumber": 1234, - "itemCount": 42, - "status": "pending" -} -``` - -## Embedding Example -Let's assume there is an "Orders" resource which is a collection of all orders from different authors. There is the relation between the Orders resource and possibly many Order resources. - -We could express this in the `_links` object using the `order` relation, but sometimes it is practical to "embed" (entirely or partially) related resources representations in the originating resource representation. For a scenario like this HAL offers the `_embedded` field. - -The `_embedded` field's object just contains the related resources HAL representations: - - -```json -{ - "_links": { - "self": { "href": "/orders" } - }, - "_embedded": { - "order": [ - { - "_links": { - "self": { "href": "/orders/1" } - }, - "orderNumber": "1", - "status": "pending" - }, - { - "_links": { - "self": { "href": "/orders/2" } - }, - "orderNumber": "2", - "status": "cancelled" - } - ] - } -} - -``` - -It is important to understand that embedded resource representation might be only **partial** and might also contain their own embedded resources. - -The embedded resource representation should be used as a **convenience** function (e.g. to reduce the initial number of calls needed at application launch). - -Where a full and up-to-date representation of a resource is needed the link relation should exercise the affordance (e.g. `GET /orders/2`). - -#### Real-world Examples - -Some APIs using HAL: - -- [Amazon AppStream REST API](http://docs.aws.amazon.com/appstream/latest/developerguide/appstream-api-rest.html) -- [FoxyCart](https://wiki.foxycart.com/v/2.0/start) -- [Clarify.io](http://docs.clarify.io/overview/) -- [University of Oxford / Mobile Oxford](http://api.m.ox.ac.uk/browser/#/) - - -## Working with HAL -Refer to the [extensive list of libraries that work with HAL](https://github.com/mikekelly/hal_specification/wiki/Libraries). - -### Spring Framework -Spring framework supports HAL out of the box. More info can be found in [Spring Documentation](https://spring.io/guides/gs/rest-hateoas/) -and [examples](https://github.com/spring-guides/gs-rest-hateoas). diff --git a/protocol/separate-concerns.md b/protocol/separate-concerns.md index f8380eb..e69de29 100644 --- a/protocol/separate-concerns.md +++ b/protocol/separate-concerns.md @@ -1,49 +0,0 @@ -# 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 - - -#### Example 1 -The rule - -> A resource identifier–URI **MUST** be used to indicate identity only - -implies there **MUST NOT** be any information about the representation media type, version of the resource or anything else in the URI. - -For example, URIs `/greeting.json` or `/v2.1.3/greeting` are **illegal** as they are not used for identification of a resource only but they convey the information about representation format or version. URIs are not meant to carry any other information but the identifier of the resource. - - -#### Example 2 -The rule - -> HTTP message body MUST be used to transfer the message content - -Implies an HTTP GET request **MUST NOT** use HTTP message body to identify the resource. For example a request: - -``` -GET /greeting HTTP/1.1 -Content-Type: application/json -... - - -{ - "filter": "string" - "depth": 3 -} -``` - -is **not acceptable** (ignoring the fact that HTTP GET method shouldn't have the body). To express identity use URI and query parameters instead e.g. `/greeting?filter=string&depth=3`. - ---- - -> _Keep things simple while designing by separating the concerns between the different parts of the request and response cycle. Keeping simple rules here allows for greater focus on larger and harder problems._ -> -> _Requests and responses will be made to address a particular resource or collection. Use the path to indicate identity, the body to transfer the contents and headers to communicate metadata. Query params may be used as a means to pass header information also in edge cases, but headers are preferred as they are more flexible and can convey more diverse information._ -> -> _– [Heroku HTTP API Design Guide](https://geemus.gitbooks.io/http-api-design/content/en/foundations/separate-concerns.html)_ diff --git a/protocol/tls.md b/protocol/tls.md index 1dad60a..e69de29 100644 --- a/protocol/tls.md +++ b/protocol/tls.md @@ -1,4 +0,0 @@ -# Transport Layer Security (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. \ No newline at end of file diff --git a/protocol/use-appropriate-methods.md b/protocol/use-appropriate-methods.md index fc40a44..e69de29 100644 --- a/protocol/use-appropriate-methods.md +++ b/protocol/use-appropriate-methods.md @@ -1,45 +0,0 @@ -# Use Appropriate Request Methods -Every API **MUST** use appropriate [HTTP request methods](https://github.com/for-GET/know-your-http-well/blob/master/methods.md) for every operation. - -Every API designer, implementer and consumer **MUST** understand the semantic of the HTTP METHOD she is using. - -At a minimum everyone **MUST** be familiar with the semantics of ["Common" HTTP Request Methods](https://github.com/for-GET/know-your-http-well/blob/master/methods.md#common): **DELETE**, **GET**, **HEAD**, **PUT**, **POST** and the [**PATCH** HTTP Request Method](https://tools.ietf.org/html/rfc5789#section-2). In addition, everyone **MUST** be aware which methods are **Safe**, **Idempotent** and **Cacheable**. - -### Safe Methods -As per HTTP specification, the **GET** and **HEAD** methods should be used only for retrieval of resource representations – and they do not update/delete the resource on the server. Both methods are said to be considered “safe“. -This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested – and they can update/delete the resource on the server and so should be used carefully. - - -### Idempotent Methods -The term idempotent is used more comprehensively to describe an operation that will produce the same results if executed once or multiple times. This is a beneficial property in many situations, as it means that a transaction can be repeated or retried as often as necessary without causing unintended effects. With non-idempotent operations, the algorithm may have to keep track of whether the operation was already performed or not. -In HTTP specification, The methods **GET**, **HEAD**, **PUT** and **DELETE** are declared idempotent methods. Other methods OPTIONS and TRACE **SHOULD NOT** have side effects, so both are also inherently idempotent. - -### Cacheable Methods -Request methods are considered "cacheable" if it is possible and useful to answer a current client request with a stored response from a prior request. **GET** and **HEAD** are defined to be cacheable. - ---- - -#### Example 1 -> GET /user/new -> Description: Creates new user - -Using GET for unsafe non-idempotent operations is **not acceptable**. - -#### Example 2 -> POST /status -> Description: Updates the status of a user approval request (to “Approved” or “Rejected”) - -Using the POST method for a status update is **not acceptable** (use PATCH). - -#### Example 3 -> PUT /user -> Description: Creates a new user - -Using the PUT method for creating a new resource is **not acceptable** (use POST). - -#### Example 4 -> PUT: /user -> Description: Updates some user details - -Using the PUT method for a partial update is **not acceptable** (use PATCH). - diff --git a/protocol/use-appropriate-status-codes.md b/protocol/use-appropriate-status-codes.md index 6ba5f8f..e69de29 100644 --- a/protocol/use-appropriate-status-codes.md +++ b/protocol/use-appropriate-status-codes.md @@ -1,44 +0,0 @@ -# Use Appropriate Status Codes -Every API **MUST** use the appropriate [HTTP Status Codes](https://github.com/for-GET/know-your-http-well/blob/master/status-codes.md) to communicate the result of a request operation. - -Every API designer, implementer and consumer **MUST** understand the semantic of the HTTP Status Code she is using. - -At a minimum everyone **MUST** be familiar with the semantics of ["Common" HTTP Status Codes](https://github.com/for-GET/know-your-http-well/blob/master/status-codes.md#common). - -#### Example - -#### Use Codes 4xx or 5xx to Communicate Errors -A request: - -``` -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: - -``` -HTTP/1.1 200 OK -Content-Type: application/json -... - - -{ - "code": "NOT_FOUND_ERR_CODE" - "message" "Order 1234 wasn't found" -} -``` -is **not acceptable**. - -Instead the - -``` -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) - diff --git a/core-principles/contract.md b/rest/README.md similarity index 100% rename from core-principles/contract.md rename to rest/README.md diff --git a/application/README.md b/rest/application/README.md similarity index 100% rename from application/README.md rename to rest/application/README.md diff --git a/rest/application/common-data-types.md b/rest/application/common-data-types.md new file mode 100644 index 0000000..a00d03d --- /dev/null +++ b/rest/application/common-data-types.md @@ -0,0 +1,37 @@ +# Common Data Types + +## Date and Time Format +Date and Time **MUST** always conform to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format e.g.: `2017-06-21T14:07:17Z` (date time) or `2017-06-21` (date), it **MUST** use the UTC (without time offsets). + +## Duration Format +Duration format **MUST** conform to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard e.g.: `P3Y6M4DT12H30M5S` (three years, six months, four days, twelve hours, thirty minutes, and five seconds). + +## Time Interval Format +Time Interval format **MUST** conform to the [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) standard e.g.: `2007-03-01T13:00:00Z/2008-05-11T15:30:00Z`. + +## Standard Time Stamps +Where applicable, a resource representation **SHOULD** contain the standard timestamps: + +- `createdAt` +- `updatedAt` +- `finishedAt` + +#### Example + +```json +{ + "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. diff --git a/application/harmonize-data.md b/rest/application/harmonize-data.md similarity index 100% rename from application/harmonize-data.md rename to rest/application/harmonize-data.md diff --git a/clients/README.md b/rest/clients/README.md similarity index 100% rename from clients/README.md rename to rest/clients/README.md diff --git a/clients/loose-coupling.md b/rest/clients/loose-coupling.md similarity index 100% rename from clients/loose-coupling.md rename to rest/clients/loose-coupling.md diff --git a/core-principles/README.md b/rest/core-principles/README.md similarity index 100% rename from core-principles/README.md rename to rest/core-principles/README.md diff --git a/core-principles/rules-for-extending.md b/rest/core-principles/api-first.md similarity index 100% rename from core-principles/rules-for-extending.md rename to rest/core-principles/api-first.md diff --git a/rest/core-principles/apiary.md b/rest/core-principles/apiary.md new file mode 100644 index 0000000..aa4985e --- /dev/null +++ b/rest/core-principles/apiary.md @@ -0,0 +1,16 @@ +# 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. + + + diff --git a/core-principles/version-control-system.md b/rest/core-principles/contract.md similarity index 100% rename from core-principles/version-control-system.md rename to rest/core-principles/contract.md diff --git a/evolution/json.md b/rest/core-principles/core-principles.md similarity index 100% rename from evolution/json.md rename to rest/core-principles/core-principles.md diff --git a/rest/core-principles/design-maturity.md b/rest/core-principles/design-maturity.md new file mode 100644 index 0000000..5ed72de --- /dev/null +++ b/rest/core-principles/design-maturity.md @@ -0,0 +1,16 @@ +# 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)). diff --git a/rest/core-principles/introduction.md b/rest/core-principles/introduction.md new file mode 100644 index 0000000..deea0b3 --- /dev/null +++ b/rest/core-principles/introduction.md @@ -0,0 +1,45 @@ +# 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 General Guidelines. + +The REST API Guidelines are further split into the following parts: + +* **Core Principles** + + 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. + + * [**Message level**](https://adidas-group.gitbooks.io/api-guidelines/content/message/) + + The Message guidelines define the structure and semantics of messages used to exchange information. + + * [**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. + + * [**Evolution**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/) + + Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. + + * [**Execution**](https://adidas-group.gitbooks.io/api-guidelines/content/execution/) + + Execution qualities governance, such as security and usability. + +* **Guides** + Guides and materials supporting the REST API Guidelines + +* **API Clients** + + Section dedicated to consumers of adidas APIs + + + diff --git a/rest/core-principles/openapi-specification.md b/rest/core-principles/openapi-specification.md new file mode 100644 index 0000000..c54f215 --- /dev/null +++ b/rest/core-principles/openapi-specification.md @@ -0,0 +1,7 @@ +# 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. + +## Language +The API description MUST be written in **American English**. diff --git a/execution/security.md b/rest/core-principles/quality.md similarity index 100% rename from execution/security.md rename to rest/core-principles/quality.md diff --git a/rest/core-principles/testing.md b/rest/core-principles/testing.md new file mode 100644 index 0000000..9a8ca38 --- /dev/null +++ b/rest/core-principles/testing.md @@ -0,0 +1,4 @@ +# 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. diff --git a/rest/core-principles/version-control-system.md b/rest/core-principles/version-control-system.md new file mode 100644 index 0000000..e69de29 diff --git a/evolution/README.md b/rest/evolution/README.md similarity index 100% rename from evolution/README.md rename to rest/evolution/README.md diff --git a/rest/evolution/json.md b/rest/evolution/json.md new file mode 100644 index 0000000..e69de29 diff --git a/rest/evolution/naming-conventions.md b/rest/evolution/naming-conventions.md new file mode 100644 index 0000000..8e25cf0 --- /dev/null +++ b/rest/evolution/naming-conventions.md @@ -0,0 +1,117 @@ +# Naming Conventions + +## General Naming Rules + +- Use American English +- Don't use acronyms +- Use `camelCase` unless stated otherwise +- Reconcile terms with adidas CDM + +Every identifier **MUST** be in American English and written in `lowercase`. An identifier **SHOULD NOT** contain acronyms. CamelCase (`camelCase`) **MUST** be used to delimit combined words. + +## URI +Every URI **MUST** follow the General Rules except for the `camelCase` rule. Instead, a hyphen (`-`) **SHOULD** be used to delimit combined words (kebab-case). Besides, a URI **MUST NOT** end with a trailing slash (`/`). + +#### Example +A well-formed URI: + +``` +/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. + +#### Example +A well-formed URI Template Variable: + +``` +/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 +{ + "_links": { + "self": { + "href": "/orders/1234" + }, + "author": { + "href": "/users/john" + } + }, + "orderNumber": 1234, + "itemCount": 42, + "status": "pending" +} +``` + +## Relation Type Identifier +Every custom [relation identifier](https://github.com/for-GET/know-your-http-well/blob/master/relations.md) **MUST** be in `lowercase` with words separated by the hyphen (`-`). + +#### Example +A well-formed resource representation with custom relation `fulfillment-provider`: + +```json +{ + "_links": { + "fulfillment-provider": { + "href": "/users/natalie" + } + } +} +``` + + +## HTTP Headers +Every HTTP Header should use `Hyphenated-Pascal-Case`. A custom HTTP Header **SHOULD NOT** start with `X-` ([RFC6648](https://tools.ietf.org/html/rfc6648)). + +#### Example + +``` +Order-Metadata-Header: 42 +``` + + +## API Description +Naming conventions within API Description document. + +### API Name +Every API Description API name **MUST** start with API domain enclosed in square brackets (e.g. `[API Domain] My API`). Words **MUST** be separated by space. + +#### Example + +```yaml +swagger: '2.0' +info: + version: '1.0.0' + title: '[Demo] Orders API' +``` + +### Resource Name +Every resource **MUST** have a name (defined by `x-summary` field). Resource name **MUST** be in `Title Case`. Words **MUST** be separated by a space. + +#### Example +```yaml +/orders: + x-summary: List of Orders +``` + +### Action Name +Every action (operation) **MUST** have a name (defined by `summary` field). Action name **MUST** be in `Title Case`. Words **MUST** be separated by a space. + +#### Example +```yaml +get: + summary: Retrieve List of Orders +``` diff --git a/evolution/reserved-identifiers.md b/rest/evolution/reserved-identifiers.md similarity index 100% rename from evolution/reserved-identifiers.md rename to rest/evolution/reserved-identifiers.md diff --git a/rest/evolution/uri-structure.md b/rest/evolution/uri-structure.md new file mode 100644 index 0000000..a9ecbcd --- /dev/null +++ b/rest/evolution/uri-structure.md @@ -0,0 +1,8 @@ +# URI Design +URI is meant to express a **identity of a resource**. URI is an identifier and it **MUST NOT** convey any other information. + +The API design process **MUST NOT** start with the design of URIs. Contrary, the URI **SHOULD** be amongst the last few things added to the API design. + +At adidas, URIs are subject to [naming conventions](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). diff --git a/rest/evolution/versioning.md b/rest/evolution/versioning.md new file mode 100644 index 0000000..a45eedc --- /dev/null +++ b/rest/evolution/versioning.md @@ -0,0 +1,102 @@ +# Changes and Versioning + +> _The fundamental principle is that you can’t break existing clients, because you don’t know what they implement, and you don’t control them. In doing so, you need to turn a backwards-incompatible change into a compatible one._ +> +> _– _[_Mark Nottingham_](https://www.mnot.net/blog/2011/10/25/web_api_versioning_smackdown) + +Any change to an API **MUST NOT** break existing clients. + +Any change to: +1. **Resource identifier** \(resource name / URI\) including any **query parameters** and their semantics +1. **Resource metadata** \(e.g. HTTP headers\) +1. **Action** the resource affords \(e.g. available HTTP Methods\) +1. **Relation** with other resources \(e.g Links\) +1. **Representation format** \(e.g. HTTP request and response bodies\) + +**MUST** follow the [**Rules for Extending**](https://adidas-group.gitbooks.io/api-guidelines/content/core-principles/rules-for-extending.html). + +## Identifier Stability \(No URI Versioning\) + +A change **MUST NOT** affect **existing** resource identifiers \(name / URI\). Furthermore, a resource identifier **MUST NOT** contain a semantic version to convey a version of resource or its representation format. + +> _The reason to make a real REST API is to get evolvability … a "v1" is a .... to your API customers, indicating RPC/HTTP \(not REST\)_ +> +> _– _[_Roy T. Fielding_](https://twitter.com/fielding/status/376835835670167552) + +#### Example + +Adding a new action to existing resource with identifier `/greeting` doesn't change its identifier to `/v2/greeting` \(or `/greeting-with-new-action` etc.\). + +## Backward-incompatible Changes + +A change to _resource identifier_, _resource metadata_, _resource actions_ and _resource relations_ that can't follow the [Rules for Extending](https://adidas-group.gitbooks.io/api-guidelines/content/core-principles/rules-for-extending.html) **MUST** result into a **new resource variant**. Existing resource variant **MUST** be preserved. + +A change to _representation format_ **SHOULD NOT** result into a new resource variant. + +#### Example + +Currently, optional URI Query Parameter `first` on an existing resource `/greeting?first=John&last=Appleseed` needs to be made required. Since this change violates the 3rd rule of extending and could break existing clients a new variant of the resource is created with different URI `/named-greeting?first=John&last=Appleseed`. + +### Representation Format Changes + +> A representation format is the serialization format \(media type\) used in request and response bodies, and typically it represents a resource or its part, possibly with additional hypermedia controls. + +If a change can't follow the Rules for Extending the representation format media type **MUST** be changed. If the media type has been changed the previous media type, **MUST** be available via [Content Negotiation](https://adidas-group.gitbooks.io/api-guidelines/content/message/content-negotiation.html). + +If the media type conveys the version parameter, the version parameter **SHOULD** follow [Semantic versioning](http://semver.org/). + +#### Example + +Media type _before_ a breaking change: + +``` +application/vnd.example.resource+json; version=2 +``` + +Media type _after_ a breaking change: + +``` +application/vnd.example.resource+json; version=3 +``` + +> NOTE: In the case of technical limitations with semi-colon separated HTTP header values, the semantic version MAY be incorporated in the media type identifier, for example: `application/vnd.example.resource.v2+json` However, the use of semicolon-separated version information is preferred. + +## API Description Versioning + +API Description in the OpenAPI specification format **MUST** have the `version` field. The `version` field **MUST** follow [Semantic versioning](http://semver.org/): + +> Given a version number MAJOR.MINOR.PATCH, increment the: +> +> * MAJOR version when you make **incompatible** API changes, +> * MINOR version when you add functionality in a **backwards-compatible** manner +> * PATCH version when you make **backwards-compatible bug fixes** + +The API Description version **SHOULD** be updated accordingly to API design change. + +#### Example + +Following API Description + +```yaml +swagger: '2.0' +info: + version: '2.1.3' + title: '[Demo] Inventory API' + description: 'Inventory service API' +``` + +Has MAJOR version 2, MINOR version 1 and PATCH version 3. + +#### Demo + +API description \(OAS2\) files demonstrating a proposal of an backward-incompatible change turned into a backward compatible change are available at [Bitbucket \(diff\) ](https://bitbucket.org/apidesigner/demo-versioning-api/pull-requests/1/add-name-parameter/diff)and documented in Apiary: + +* [Production version](https://demoversioningproduction.docs.apiary.io/#) as being consumed by clients +* [Development version](https://demoversioningdevelopment.docs.apiary.io/#) proposing a backward incompatible change + +#### Recommended Reading + +* [Evolving HTTP APIs](https://www.mnot.net/blog/2012/12/04/api-evolution) + + + diff --git a/examples.md b/rest/examples.md similarity index 100% rename from examples.md rename to rest/examples.md diff --git a/rest/execution/README.md b/rest/execution/README.md new file mode 100644 index 0000000..3477681 --- /dev/null +++ b/rest/execution/README.md @@ -0,0 +1,2 @@ +# Execution +Performance qualities, such as security and usability, which are observable at run time. diff --git a/execution/api-keys.md b/rest/execution/api-keys.md similarity index 100% rename from execution/api-keys.md rename to rest/execution/api-keys.md diff --git a/rest/execution/asynchronous-tasks.md b/rest/execution/asynchronous-tasks.md new file mode 100644 index 0000000..2c61486 --- /dev/null +++ b/rest/execution/asynchronous-tasks.md @@ -0,0 +1,26 @@ +# 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. + +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. + +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. + +3. Task 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. + diff --git a/execution/authentication.md b/rest/execution/authentication.md similarity index 100% rename from execution/authentication.md rename to rest/execution/authentication.md diff --git a/execution/batch-operations.md b/rest/execution/batch-operations.md similarity index 100% rename from execution/batch-operations.md rename to rest/execution/batch-operations.md diff --git a/rest/execution/caching.md b/rest/execution/caching.md new file mode 100644 index 0000000..1fe746d --- /dev/null +++ b/rest/execution/caching.md @@ -0,0 +1,45 @@ +# 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)). + +## 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. + + +### 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. + +#### 1. Cache Expiration & Revalidation +The common scenario to set cache expiration and revalidation policy is to use the `max-age` and `must-revalidate` directives: + +``` +HTTP/1.1 200 OK +Date: Mon, 19 Aug 2017 00:00:00 CEST +Last-Modified: Mon, 19 Aug 2017 00:00:00 CEST +Cache-Control: max-age=3600,must-revalidate +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: + +``` +HTTP/1.1 200 OK +Date: Mon, 19 Aug 2017 00:00:00 CEST +Last-Modified: Mon, 19 Aug 2017 00:00:00 CEST +Cache-Control: no-cache, no-store, must-revalidate +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. diff --git a/rest/execution/choosing-fields-and-embedded-resoruces.md b/rest/execution/choosing-fields-and-embedded-resoruces.md new file mode 100644 index 0000000..515738c --- /dev/null +++ b/rest/execution/choosing-fields-and-embedded-resoruces.md @@ -0,0 +1,80 @@ +# Choosing Fields & 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`). + +#### Example +Retrieve only some details of an Order resource: + +HTTP Request +``` +GET /order/1234?fields=_links,orderNumber,status HTTP/1.1 +Accept: application/hal+json +``` + +HTTP Response +``` +HTTP/1.1 200 OK +Content-Type: application/hal+json + +{ + "_links": { + "self": { "href": "/orders/1234" }, + "author": { "href": "/users/john" }, + "items": [ ... ] + }, + "orderNumber": 1234, + "status": "pending" +} +``` + +## 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. + + +#### Example +Embed only information about the Author of an Order resource. We are not interested in Items that are in this order. + +HTTP Request + +``` +GET /order/1234?embed=author HTTP/1.1 +Accept: application/hal+json +``` + +HTTP Response +``` +HTTP/1.1 200 OK +Content-Type: application/hal+json + +{ + "_links": { + "self": { "href": "/orders/1234" }, + "author": { "href": "/users/john" }, + "items": [ ... ] + }, + "orderNumber": 1234, + "itemCount": 42, + "status": "pending", + "_embedded": { + "author": { + "_links": { "self": "/users/john" }, + "name": "John Appleseed", + "email": "john@apple.com" + } + } +} +``` + +## 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. diff --git a/rest/execution/localization.md b/rest/execution/localization.md new file mode 100644 index 0000000..eb96e61 --- /dev/null +++ b/rest/execution/localization.md @@ -0,0 +1,37 @@ +# 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 + +``` +GET /article HTTP/1.1 +Accept-Language: en,en-US,fr;q=0.6 +``` + +``` +HTTP/1.1 200 OK +Content-Type: application/hal+json;charset=UTF-8 +Content-Language: en +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 + +``` +GET /article?market=en_US HTTP/1.1 +``` +``` +HTTP/1.1 200 OK +Content-Type: application/hal+json;charset=UTF-8 +Content-Language: en +Vary: Accept-Language + +... +``` diff --git a/rest/execution/pagination.md b/rest/execution/pagination.md new file mode 100644 index 0000000..fc4a22c --- /dev/null +++ b/rest/execution/pagination.md @@ -0,0 +1,27 @@ +# 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 +The Collection of Orders using the collection navigation link and `offset` and `limit` query parameters: + + +```json +{ + "_links": { + "self": { "href": "/orders?offset=100&limit=10" }, + "prev": { "href": "/orders?offset=90&limit=10" }, + "next": { "href": "/orders?offset=110&limit=10" }, + "first": { "href": "/orders?limit=10" }, + "last": { "href": "/orders?offset=900&limit=10" } + }, + "total_count": 910, + "_embedded": { + "order": [ + { ... }, + { ... }, + + ... + ] + } +} +``` diff --git a/rest/execution/query-requests-with-large-inputs.md b/rest/execution/query-requests-with-large-inputs.md new file mode 100644 index 0000000..6d6bb87 --- /dev/null +++ b/rest/execution/query-requests-with-large-inputs.md @@ -0,0 +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). + +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 + +``` +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._ diff --git a/rest/execution/rate-limiting.md b/rest/execution/rate-limiting.md new file mode 100644 index 0000000..3d96593 --- /dev/null +++ b/rest/execution/rate-limiting.md @@ -0,0 +1,63 @@ +# 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. + +## 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: + +``` +HTTP/1.1 403 Forbidden +Content-Type: application/problem+json + +X-Error-Detail-Header: Account Over Rate Limit +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 +Example response to a request over the throttle limit: + +``` +HTTP/1.1 403 Forbidden +Content-Type: application/problem+json + +Retry-After: 1 +X-Error-Detail-Header: Account Over Queries Per Second Limit +X-Mashery-Error-Code: ERR_403_DEVELOPER_OVER_QPS + +{ + "title": "Quota Limit Exceeded", + "detail": "Account Over Queries Per Second Limit" +} +``` + +> 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: + +``` +HTTP/1.1 200 OK + +X-Plan-QPS-Allotted: 10 +X-Plan-QPS-Current: 1 +X-Plan-Quota-Allotted: 1000 +X-Plan-Quota-Current: 2 +X-Plan-Quota-Reset: Tuesday, June 6, 2017 12:00:00 AM GMT +``` diff --git a/execution/search-requests.md b/rest/execution/search-requests.md similarity index 100% rename from execution/search-requests.md rename to rest/execution/search-requests.md diff --git a/rest/execution/security.md b/rest/execution/security.md new file mode 100644 index 0000000..e69de29 diff --git a/rest/execution/testing-enviroments.md b/rest/execution/testing-enviroments.md new file mode 100644 index 0000000..f51c49a --- /dev/null +++ b/rest/execution/testing-enviroments.md @@ -0,0 +1,3 @@ +# Testing Environments +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. + diff --git a/rest/guides/README.md b/rest/guides/README.md new file mode 100644 index 0000000..bf7dfc5 --- /dev/null +++ b/rest/guides/README.md @@ -0,0 +1,9 @@ +# 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 \ No newline at end of file diff --git a/rest/guides/api-testing-ci-environment.md b/rest/guides/api-testing-ci-environment.md new file mode 100644 index 0000000..49fd22e --- /dev/null +++ b/rest/guides/api-testing-ci-environment.md @@ -0,0 +1,101 @@ +# 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 (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. diff --git a/guides/complete-api-development.md b/rest/guides/complete-api-development.md similarity index 100% rename from guides/complete-api-development.md rename to rest/guides/complete-api-development.md diff --git a/message/README.md b/rest/message/README.md similarity index 100% rename from message/README.md rename to rest/message/README.md diff --git a/rest/message/content-negotiation.md b/rest/message/content-negotiation.md new file mode 100644 index 0000000..bd71338 --- /dev/null +++ b/rest/message/content-negotiation.md @@ -0,0 +1,28 @@ + +# 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: + +``` +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: + +``` +HTTP/1.1 200 OK +Content-Type: application/vnd.example.resource+json; version=2.1.3 +... +``` + +> NOTE: A server that doesn't have the requested representation media type available MUST respond with the HTTP Status Code **406 Not Acceptable**. +> +> NOTE: A server MAY have multiple choices available and MAY respond with the **300 Multiple Choices** response. In which case client SHOULD choose from the presented choices. +> +> You can read more about content negotiation at [MDN Content negotiation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation). diff --git a/rest/message/error-reporting.md b/rest/message/error-reporting.md new file mode 100644 index 0000000..d43451b --- /dev/null +++ b/rest/message/error-reporting.md @@ -0,0 +1,120 @@ +# Problem Detail +The [`application/problem+json`](https://tools.ietf.org/html/rfc7807) (Problem Detail) **MUST** be used to communicate details about an error. + +Problem Detail is intended for use with the HTTP status codes 4xx and 5xx. Problem Detail **MUST NOT** be used with 2xx status code responses. + +At the minimum, any Problem Detail response **MUST** have the `title` and `detail` fields. + +#### Example + +```json +{ + "title": "Authentication required", + "detail": "Missing authentication credentials for the Greeting resource." +} +``` + +## Optional Fields +It **SHOULD** has the `type` field with the identifier of the error, besides it **MAY** have the `instance` field with the URI of the resource in question. If the Problem Detail response has the `status` field it **MUST** have the same value as HTTP Status code from of the response. + + +```json +{ + "type": "https://adidas-group.com/problems/scv/unauthorized", + "title": "Authentication required", + "detail": "Missing authentication credentials for the Greeting resource.", + "instance": "/greeting", + "status": 401 +} +``` + +> NOTE: The `type` field is an identifier, and as such it **MAY** be used to denote additional error codes. Keep in mind that the identifier should be a URI. + +## Additional Fields +If needed, the Problem Detail **MAY** include additional fields, refer to [RFC7807](https://tools.ietf.org/html/rfc7807) for details. + +## Validation Errors +When necessary, a Problem Detail response **MAY** include additional error details about the problems that have occurred. + +These additional errors **MUST** be under the `errors` and **MUST** follow the Problem Detail structure. + +#### Example + +Request: + +``` +POST /my-resource HTTP/1.1 +Content-Type: application/json + +{ + "age": -32, + "color": "cyan" +} +``` + +Response: + +``` +HTTP/1.1 400 Bad Request +Content-Type: application/problem+json +Content-Language: en + +{ + "type": "https://example.net/validation_error", + "title": "Your request parameters didn't validate.", + "instance": "/my-resource", + "status": 400, + + "errors": [ + { + "type": "https://example.net/invalid_params", + "instance": "/age", + "title": "Invalid Parameter", + "detail": "age must be a positive integer" + }, + { + "type": "https://example.net/invalid_params", + "instance": "/color", + "title": "Invalid Parameter", + "detail": "color must be 'green', 'red' or 'blue'" + } + ] +} +``` + + + +## Problem Detail and Content Negotiation +#### Example +A request is made to retrieve a resource representation: + +``` +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: + +``` +HTTP/1.1 401 Unauthorized +Content-Type: application/problem+json +Content-Language: en + +{ + "type": "https://adidas-group.com/problems/scv/unauthorized", + "title": "Authentication required", + "detail": "Missing authentication credentials for the Greeting resource.", + "instance": "/greeting", + "status": 401 +} +``` + +## No Stack Traces or Server Logs +> _Problem details are not a debugging tool for the underlying implementation; rather, they are a way to expose greater detail about the HTTP interface itself._ +> +> _– [RFC7807](https://tools.ietf.org/html/rfc7807)_ + +A Problem Detail response **MUST NOT** contain a program stack trace or server log for debugging purposes. Instead, provide a `logref` field with reference to the particular server log. + +## Working with Problem Detail +There are a whole plethora of libraries working with Problem Detail, for example, see [Zalando / Problem](https://github.com/zalando/problem) (Java). diff --git a/rest/message/foreign-key-relations.md b/rest/message/foreign-key-relations.md new file mode 100644 index 0000000..6df2fe3 --- /dev/null +++ b/rest/message/foreign-key-relations.md @@ -0,0 +1,67 @@ +# Foreign Key Relations + +## Link or Embed Foreign Key Relation +When a resource representation includes relation with another (foreign) resource, the relation **MUST** be expressed as a link relation or embed the related resource. + +#### Example +Use: + +```json +{ + "_links": { + "author": { "href": "/users/john" } + ... + } + ... +} +``` + +or: + +```json +{ + ... + "_embedded": { + "author": { + "_links": { "self": "/users/john" }, + "name": "John Appleseed", + "email": "john@apple.com" + } + } +} +``` + +instead: + +```json +{ + ... + "authorHref": "/users/john" +} +``` + +## Nest Foreign Key Relation +If a foreign object has another identifier, but URI or the foreign object isn't a resource, the object **MUST** be nested. + +#### Example +Use: + +```json +{ + "author": { + "id": "1234", + "name": "John Appleseed", + "email": "john@apple.com" + } +} +``` + +instead: + +```json +{ + "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. diff --git a/rest/message/hal.md b/rest/message/hal.md new file mode 100644 index 0000000..553eb7d --- /dev/null +++ b/rest/message/hal.md @@ -0,0 +1,114 @@ +# HAL +The [`application/hal+json`](http://stateless.co/hal_specification.html) (HAL) **MUST** be used as the representation format of a resource. + +## Introduction to HAL +> _HAL is a simple format that gives a consistent and easy way to hyperlink between resources in your API._ + +This document is an informal introduction to the HAL media type. For more details see [HAL - Hypertext Application Language Specification](http://stateless.co/hal_specification.html). + +## Simple Document Example +The simplest Hal document looks like an empty JSON (it is an empty JSON!): + +```json +{ +} +``` + +A document representing a "Greeting" resource might look like: + +```json +{ + "message": "Hello World!", + "_links": { + "self": { + "href": "/greeting" + } + } +} +``` +The field `_links` has a special meaning in HAL. It denotes a list of link relations - a pair of a relation identifier and a link (URI). + +These link relations are used to express the relation of a resource with other resources. + +In our case the "Greeting" resource isn't related to other resources but itself, hence the `self` relation pointing to the Greeting resource. + +> NOTE: It is **customary** for every resource representation to include the `self` link relation. + +> NOTE: The href **MUST** always be **relative path to the API root** (e.g. without the host and scheme). + +## Relation Example +A more complex document example could be an "Order" resource that has a related resource "Author" (a person who created the order. It might look like: + +```json +{ + "_links": { + "self": { + "href": "/orders/1234" + }, + "author": { + "href": "/users/john" + } + }, + "orderNumber": 1234, + "itemCount": 42, + "status": "pending" +} +``` + +## Embedding Example +Let's assume there is an "Orders" resource which is a collection of all orders from different authors. There is the relation between the Orders resource and possibly many Order resources. + +We could express this in the `_links` object using the `order` relation, but sometimes it is practical to "embed" (entirely or partially) related resources representations in the originating resource representation. For a scenario like this HAL offers the `_embedded` field. + +The `_embedded` field's object just contains the related resources HAL representations: + + +```json +{ + "_links": { + "self": { "href": "/orders" } + }, + "_embedded": { + "order": [ + { + "_links": { + "self": { "href": "/orders/1" } + }, + "orderNumber": "1", + "status": "pending" + }, + { + "_links": { + "self": { "href": "/orders/2" } + }, + "orderNumber": "2", + "status": "cancelled" + } + ] + } +} + +``` + +It is important to understand that embedded resource representation might be only **partial** and might also contain their own embedded resources. + +The embedded resource representation should be used as a **convenience** function (e.g. to reduce the initial number of calls needed at application launch). + +Where a full and up-to-date representation of a resource is needed the link relation should exercise the affordance (e.g. `GET /orders/2`). + +#### Real-world Examples + +Some APIs using HAL: + +- [Amazon AppStream REST API](http://docs.aws.amazon.com/appstream/latest/developerguide/appstream-api-rest.html) +- [FoxyCart](https://wiki.foxycart.com/v/2.0/start) +- [Clarify.io](http://docs.clarify.io/overview/) +- [University of Oxford / Mobile Oxford](http://api.m.ox.ac.uk/browser/#/) + + +## Working with HAL +Refer to the [extensive list of libraries that work with HAL](https://github.com/mikekelly/hal_specification/wiki/Libraries). + +### Spring Framework +Spring framework supports HAL out of the box. More info can be found in [Spring Documentation](https://spring.io/guides/gs/rest-hateoas/) +and [examples](https://github.com/spring-guides/gs-rest-hateoas). diff --git a/message/message-formats.md b/rest/message/message-formats.md similarity index 100% rename from message/message-formats.md rename to rest/message/message-formats.md diff --git a/miscellaneous.md b/rest/miscellaneous.md similarity index 100% rename from miscellaneous.md rename to rest/miscellaneous.md diff --git a/protocol/README.md b/rest/protocol/README.md similarity index 100% rename from protocol/README.md rename to rest/protocol/README.md diff --git a/protocol/http.md b/rest/protocol/http.md similarity index 100% rename from protocol/http.md rename to rest/protocol/http.md diff --git a/protocol/know-your-http.md b/rest/protocol/know-your-http.md similarity index 100% rename from protocol/know-your-http.md rename to rest/protocol/know-your-http.md diff --git a/rest/protocol/message.md b/rest/protocol/message.md new file mode 100644 index 0000000..e69de29 diff --git a/rest/protocol/protocol.md b/rest/protocol/protocol.md new file mode 100644 index 0000000..e69de29 diff --git a/rest/protocol/separate-concerns.md b/rest/protocol/separate-concerns.md new file mode 100644 index 0000000..f8380eb --- /dev/null +++ b/rest/protocol/separate-concerns.md @@ -0,0 +1,49 @@ +# Separate Concerns +Every API using HTTP/S API **MUST** precisely follow the concern separation of an HTTP message: + +1. A _resource identifier_–URI **MUST** be used to indicate **identity** only +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 + + +#### Example 1 +The rule + +> A resource identifier–URI **MUST** be used to indicate identity only + +implies there **MUST NOT** be any information about the representation media type, version of the resource or anything else in the URI. + +For example, URIs `/greeting.json` or `/v2.1.3/greeting` are **illegal** as they are not used for identification of a resource only but they convey the information about representation format or version. URIs are not meant to carry any other information but the identifier of the resource. + + +#### Example 2 +The rule + +> HTTP message body MUST be used to transfer the message content + +Implies an HTTP GET request **MUST NOT** use HTTP message body to identify the resource. For example a request: + +``` +GET /greeting HTTP/1.1 +Content-Type: application/json +... + + +{ + "filter": "string" + "depth": 3 +} +``` + +is **not acceptable** (ignoring the fact that HTTP GET method shouldn't have the body). To express identity use URI and query parameters instead e.g. `/greeting?filter=string&depth=3`. + +--- + +> _Keep things simple while designing by separating the concerns between the different parts of the request and response cycle. Keeping simple rules here allows for greater focus on larger and harder problems._ +> +> _Requests and responses will be made to address a particular resource or collection. Use the path to indicate identity, the body to transfer the contents and headers to communicate metadata. Query params may be used as a means to pass header information also in edge cases, but headers are preferred as they are more flexible and can convey more diverse information._ +> +> _– [Heroku HTTP API Design Guide](https://geemus.gitbooks.io/http-api-design/content/en/foundations/separate-concerns.html)_ diff --git a/rest/protocol/tls.md b/rest/protocol/tls.md new file mode 100644 index 0000000..1dad60a --- /dev/null +++ b/rest/protocol/tls.md @@ -0,0 +1,4 @@ +# Transport Layer Security (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. \ No newline at end of file diff --git a/rest/protocol/use-appropriate-methods.md b/rest/protocol/use-appropriate-methods.md new file mode 100644 index 0000000..fc40a44 --- /dev/null +++ b/rest/protocol/use-appropriate-methods.md @@ -0,0 +1,45 @@ +# Use Appropriate Request Methods +Every API **MUST** use appropriate [HTTP request methods](https://github.com/for-GET/know-your-http-well/blob/master/methods.md) for every operation. + +Every API designer, implementer and consumer **MUST** understand the semantic of the HTTP METHOD she is using. + +At a minimum everyone **MUST** be familiar with the semantics of ["Common" HTTP Request Methods](https://github.com/for-GET/know-your-http-well/blob/master/methods.md#common): **DELETE**, **GET**, **HEAD**, **PUT**, **POST** and the [**PATCH** HTTP Request Method](https://tools.ietf.org/html/rfc5789#section-2). In addition, everyone **MUST** be aware which methods are **Safe**, **Idempotent** and **Cacheable**. + +### Safe Methods +As per HTTP specification, the **GET** and **HEAD** methods should be used only for retrieval of resource representations – and they do not update/delete the resource on the server. Both methods are said to be considered “safe“. +This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested – and they can update/delete the resource on the server and so should be used carefully. + + +### Idempotent Methods +The term idempotent is used more comprehensively to describe an operation that will produce the same results if executed once or multiple times. This is a beneficial property in many situations, as it means that a transaction can be repeated or retried as often as necessary without causing unintended effects. With non-idempotent operations, the algorithm may have to keep track of whether the operation was already performed or not. +In HTTP specification, The methods **GET**, **HEAD**, **PUT** and **DELETE** are declared idempotent methods. Other methods OPTIONS and TRACE **SHOULD NOT** have side effects, so both are also inherently idempotent. + +### Cacheable Methods +Request methods are considered "cacheable" if it is possible and useful to answer a current client request with a stored response from a prior request. **GET** and **HEAD** are defined to be cacheable. + +--- + +#### Example 1 +> GET /user/new +> Description: Creates new user + +Using GET for unsafe non-idempotent operations is **not acceptable**. + +#### Example 2 +> POST /status +> Description: Updates the status of a user approval request (to “Approved” or “Rejected”) + +Using the POST method for a status update is **not acceptable** (use PATCH). + +#### Example 3 +> PUT /user +> Description: Creates a new user + +Using the PUT method for creating a new resource is **not acceptable** (use POST). + +#### Example 4 +> PUT: /user +> Description: Updates some user details + +Using the PUT method for a partial update is **not acceptable** (use PATCH). + diff --git a/rest/protocol/use-appropriate-status-codes.md b/rest/protocol/use-appropriate-status-codes.md new file mode 100644 index 0000000..6ba5f8f --- /dev/null +++ b/rest/protocol/use-appropriate-status-codes.md @@ -0,0 +1,44 @@ +# Use Appropriate Status Codes +Every API **MUST** use the appropriate [HTTP Status Codes](https://github.com/for-GET/know-your-http-well/blob/master/status-codes.md) to communicate the result of a request operation. + +Every API designer, implementer and consumer **MUST** understand the semantic of the HTTP Status Code she is using. + +At a minimum everyone **MUST** be familiar with the semantics of ["Common" HTTP Status Codes](https://github.com/for-GET/know-your-http-well/blob/master/status-codes.md#common). + +#### Example + +#### Use Codes 4xx or 5xx to Communicate Errors +A request: + +``` +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: + +``` +HTTP/1.1 200 OK +Content-Type: application/json +... + + +{ + "code": "NOT_FOUND_ERR_CODE" + "message" "Order 1234 wasn't found" +} +``` +is **not acceptable**. + +Instead the + +``` +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) + From 67d920337b8b102da0164dbb2646da2aeb53dcb1 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 12:59:35 +0000 Subject: [PATCH 11/17] Updates SUMMARY.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + application/common-data-types.md | 0 core-principles/apiary.md | 0 core-principles/core-principles.md | 0 core-principles/design-maturity.md | 0 core-principles/functional.md | 0 core-principles/introduction.md | 0 core-principles/openapi-specification.md | 0 core-principles/testing.md | 0 evolution/naming-conventions.md | 0 evolution/uri-structure.md | 0 evolution/versioning.md | 0 execution/README.md | 0 execution/asynchronous-tasks.md | 0 execution/caching.md | 0 execution/choosing-fields-and-embedded-resoruces.md | 0 execution/localization.md | 0 execution/pagination.md | 0 execution/query-requests-with-large-inputs.md | 0 execution/rate-limiting.md | 0 execution/testing-enviroments.md | 0 guides/README.md | 0 guides/api-testing-ci-environment.md | 0 message/content-negotiation.md | 0 message/error-reporting.md | 0 message/foreign-key-relations.md | 0 message/hal.md | 0 protocol/protocol.md | 0 protocol/separate-concerns.md | 0 protocol/tls.md | 0 protocol/use-appropriate-methods.md | 0 protocol/use-appropriate-status-codes.md | 0 32 files changed, 1 insertion(+) delete mode 100644 application/common-data-types.md delete mode 100644 core-principles/apiary.md delete mode 100644 core-principles/core-principles.md delete mode 100644 core-principles/design-maturity.md delete mode 100644 core-principles/functional.md delete mode 100644 core-principles/introduction.md delete mode 100644 core-principles/openapi-specification.md delete mode 100644 core-principles/testing.md delete mode 100644 evolution/naming-conventions.md delete mode 100644 evolution/uri-structure.md delete mode 100644 evolution/versioning.md delete mode 100644 execution/README.md delete mode 100644 execution/asynchronous-tasks.md delete mode 100644 execution/caching.md delete mode 100644 execution/choosing-fields-and-embedded-resoruces.md delete mode 100644 execution/localization.md delete mode 100644 execution/pagination.md delete mode 100644 execution/query-requests-with-large-inputs.md delete mode 100644 execution/rate-limiting.md delete mode 100644 execution/testing-enviroments.md delete mode 100644 guides/README.md delete mode 100644 guides/api-testing-ci-environment.md delete mode 100644 message/content-negotiation.md delete mode 100644 message/error-reporting.md delete mode 100644 message/foreign-key-relations.md delete mode 100644 message/hal.md delete mode 100644 protocol/protocol.md delete mode 100644 protocol/separate-concerns.md delete mode 100644 protocol/tls.md delete mode 100644 protocol/use-appropriate-methods.md delete mode 100644 protocol/use-appropriate-status-codes.md diff --git a/SUMMARY.md b/SUMMARY.md index eb3f93c..b2901fb 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -61,6 +61,7 @@ * [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) ## Kafka Guidelines diff --git a/application/common-data-types.md b/application/common-data-types.md deleted file mode 100644 index e69de29..0000000 diff --git a/core-principles/apiary.md b/core-principles/apiary.md deleted file mode 100644 index e69de29..0000000 diff --git a/core-principles/core-principles.md b/core-principles/core-principles.md deleted file mode 100644 index e69de29..0000000 diff --git a/core-principles/design-maturity.md b/core-principles/design-maturity.md deleted file mode 100644 index e69de29..0000000 diff --git a/core-principles/functional.md b/core-principles/functional.md deleted file mode 100644 index e69de29..0000000 diff --git a/core-principles/introduction.md b/core-principles/introduction.md deleted file mode 100644 index e69de29..0000000 diff --git a/core-principles/openapi-specification.md b/core-principles/openapi-specification.md deleted file mode 100644 index e69de29..0000000 diff --git a/core-principles/testing.md b/core-principles/testing.md deleted file mode 100644 index e69de29..0000000 diff --git a/evolution/naming-conventions.md b/evolution/naming-conventions.md deleted file mode 100644 index e69de29..0000000 diff --git a/evolution/uri-structure.md b/evolution/uri-structure.md deleted file mode 100644 index e69de29..0000000 diff --git a/evolution/versioning.md b/evolution/versioning.md deleted file mode 100644 index e69de29..0000000 diff --git a/execution/README.md b/execution/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/execution/asynchronous-tasks.md b/execution/asynchronous-tasks.md deleted file mode 100644 index e69de29..0000000 diff --git a/execution/caching.md b/execution/caching.md deleted file mode 100644 index e69de29..0000000 diff --git a/execution/choosing-fields-and-embedded-resoruces.md b/execution/choosing-fields-and-embedded-resoruces.md deleted file mode 100644 index e69de29..0000000 diff --git a/execution/localization.md b/execution/localization.md deleted file mode 100644 index e69de29..0000000 diff --git a/execution/pagination.md b/execution/pagination.md deleted file mode 100644 index e69de29..0000000 diff --git a/execution/query-requests-with-large-inputs.md b/execution/query-requests-with-large-inputs.md deleted file mode 100644 index e69de29..0000000 diff --git a/execution/rate-limiting.md b/execution/rate-limiting.md deleted file mode 100644 index e69de29..0000000 diff --git a/execution/testing-enviroments.md b/execution/testing-enviroments.md deleted file mode 100644 index e69de29..0000000 diff --git a/guides/README.md b/guides/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/guides/api-testing-ci-environment.md b/guides/api-testing-ci-environment.md deleted file mode 100644 index e69de29..0000000 diff --git a/message/content-negotiation.md b/message/content-negotiation.md deleted file mode 100644 index e69de29..0000000 diff --git a/message/error-reporting.md b/message/error-reporting.md deleted file mode 100644 index e69de29..0000000 diff --git a/message/foreign-key-relations.md b/message/foreign-key-relations.md deleted file mode 100644 index e69de29..0000000 diff --git a/message/hal.md b/message/hal.md deleted file mode 100644 index e69de29..0000000 diff --git a/protocol/protocol.md b/protocol/protocol.md deleted file mode 100644 index e69de29..0000000 diff --git a/protocol/separate-concerns.md b/protocol/separate-concerns.md deleted file mode 100644 index e69de29..0000000 diff --git a/protocol/tls.md b/protocol/tls.md deleted file mode 100644 index e69de29..0000000 diff --git a/protocol/use-appropriate-methods.md b/protocol/use-appropriate-methods.md deleted file mode 100644 index e69de29..0000000 diff --git a/protocol/use-appropriate-status-codes.md b/protocol/use-appropriate-status-codes.md deleted file mode 100644 index e69de29..0000000 From 29d867fbfb9f89c26fc3a1e690a139eec742ea2e Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 13:03:08 +0000 Subject: [PATCH 12/17] Updates SUMMARY.md Auto commit by GitBook Editor --- README.md | 2 ++ SUMMARY.md | 2 +- rest/core-principles/introduction.md | 45 ---------------------------- rest/introduction.md | 45 ++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 46 deletions(-) create mode 100644 rest/introduction.md diff --git a/README.md b/README.md index 91d8037..e49370c 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ The API Guidelines are split into two main parts: * General Guidelines * API type-specific Guidelines + * [REST APIs Guidelines](/rest/introduction.md) + * [Kafka Guidelines](/kafka/introduction.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\). diff --git a/SUMMARY.md b/SUMMARY.md index b2901fb..15af596 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -17,7 +17,7 @@ ## REST API Guidelines -* [Introduction](rest/core-principles/introduction.md) +* [Introduction](rest/introduction.md) * [Core Principles](rest/core-principles/README.md) * [OpenAPI Specification](rest/core-principles/openapi-specification.md) * [API Design Platform](rest/core-principles/apiary.md) diff --git a/rest/core-principles/introduction.md b/rest/core-principles/introduction.md index deea0b3..e69de29 100644 --- a/rest/core-principles/introduction.md +++ b/rest/core-principles/introduction.md @@ -1,45 +0,0 @@ -# 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 General Guidelines. - -The REST API Guidelines are further split into the following parts: - -* **Core Principles** - - 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. - - * [**Message level**](https://adidas-group.gitbooks.io/api-guidelines/content/message/) - - The Message guidelines define the structure and semantics of messages used to exchange information. - - * [**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. - - * [**Evolution**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/) - - Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. - - * [**Execution**](https://adidas-group.gitbooks.io/api-guidelines/content/execution/) - - Execution qualities governance, such as security and usability. - -* **Guides** - Guides and materials supporting the REST API Guidelines - -* **API Clients** - - Section dedicated to consumers of adidas APIs - - - diff --git a/rest/introduction.md b/rest/introduction.md new file mode 100644 index 0000000..deea0b3 --- /dev/null +++ b/rest/introduction.md @@ -0,0 +1,45 @@ +# 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 General Guidelines. + +The REST API Guidelines are further split into the following parts: + +* **Core Principles** + + 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. + + * [**Message level**](https://adidas-group.gitbooks.io/api-guidelines/content/message/) + + The Message guidelines define the structure and semantics of messages used to exchange information. + + * [**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. + + * [**Evolution**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/) + + Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. + + * [**Execution**](https://adidas-group.gitbooks.io/api-guidelines/content/execution/) + + Execution qualities governance, such as security and usability. + +* **Guides** + Guides and materials supporting the REST API Guidelines + +* **API Clients** + + Section dedicated to consumers of adidas APIs + + + From cc1d1c496e268cb24ad40153b5d06ab302cb3d33 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 13:06:20 +0000 Subject: [PATCH 13/17] Updates general-guidelines/introduction.md Auto commit by GitBook Editor --- SUMMARY.md | 1 + general-guidelines/introduction.md | 6 ++++++ kafka/introduction.md | 2 ++ rest/introduction.md | 6 +++++- 4 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 general-guidelines/introduction.md diff --git a/SUMMARY.md b/SUMMARY.md index 15af596..291d4b9 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -6,6 +6,7 @@ ## General Guidelines +* [Introduction](general-guidelines/introduction.md) * [API First](general-guidelines/api-first.md) * [Contract](general-guidelines/contract.md) * [Robustness](general-guidelines/robustness.md) diff --git a/general-guidelines/introduction.md b/general-guidelines/introduction.md new file mode 100644 index 0000000..c917272 --- /dev/null +++ b/general-guidelines/introduction.md @@ -0,0 +1,6 @@ +# 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. + + + diff --git a/kafka/introduction.md b/kafka/introduction.md index 7805b7d..9191687 100644 --- a/kafka/introduction.md +++ b/kafka/introduction.md @@ -1,3 +1,5 @@ +# ![](/assets/adidas-logo.svg) + # adidas Kafka Guidelines diff --git a/rest/introduction.md b/rest/introduction.md index deea0b3..7c94d44 100644 --- a/rest/introduction.md +++ b/rest/introduction.md @@ -1,6 +1,10 @@ +# ![](/assets/adidas-logo.svg) + # 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 General Guidelines. +The adidas REST API Guidelines defines standards and guidelines for building REST APIs at adidas. + +> NOTE: These Guidelines has to be followed in addition to the General Guidelines. The REST API Guidelines are further split into the following parts: From 9d962638c6b4d97bd82e45777f85d118f66b69cd Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 13:07:01 +0000 Subject: [PATCH 14/17] Updates README.md Auto commit by GitBook Editor --- README.md | 2 +- general-guidelines/introduction.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e49370c..0022cd0 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The guidelines lay down the foundation for collaboration, stability, and extensi The API Guidelines are split into two main parts: -* General Guidelines +* [General Guidelines](/general-guidelines/introduction.md) * API type-specific Guidelines * [REST APIs Guidelines](/rest/introduction.md) * [Kafka Guidelines](/kafka/introduction.md) diff --git a/general-guidelines/introduction.md b/general-guidelines/introduction.md index c917272..760c9ee 100644 --- a/general-guidelines/introduction.md +++ b/general-guidelines/introduction.md @@ -1,6 +1,6 @@ +# ![](/assets/adidas-logo.svg) + # 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. - - From 4c4b460029f9aa8dede040d52abc8fcf40838110 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 13:09:05 +0000 Subject: [PATCH 15/17] Updates README.md Auto commit by GitBook Editor --- README.md | 2 +- SUMMARY.md | 2 +- general-guidelines/README.md | 6 +++++- general-guidelines/introduction.md | 6 ------ 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0022cd0..25a7b95 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The guidelines lay down the foundation for collaboration, stability, and extensi The API Guidelines are split into two main parts: -* [General Guidelines](/general-guidelines/introduction.md) +* [General Guidelines](/general-guidelines/README.md) * API type-specific Guidelines * [REST APIs Guidelines](/rest/introduction.md) * [Kafka Guidelines](/kafka/introduction.md) diff --git a/SUMMARY.md b/SUMMARY.md index 291d4b9..c73448c 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -6,7 +6,7 @@ ## General Guidelines -* [Introduction](general-guidelines/introduction.md) +* [Introduction](general-guidelines/README.md) * [API First](general-guidelines/api-first.md) * [Contract](general-guidelines/contract.md) * [Robustness](general-guidelines/robustness.md) diff --git a/general-guidelines/README.md b/general-guidelines/README.md index 461b62a..760c9ee 100644 --- a/general-guidelines/README.md +++ b/general-guidelines/README.md @@ -1,2 +1,6 @@ -General Guidelines +# ![](/assets/adidas-logo.svg) + +# 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. diff --git a/general-guidelines/introduction.md b/general-guidelines/introduction.md index 760c9ee..e69de29 100644 --- a/general-guidelines/introduction.md +++ b/general-guidelines/introduction.md @@ -1,6 +0,0 @@ -# ![](/assets/adidas-logo.svg) - -# 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. - From edd820388e1f6d40ca888a37bec7b9509d768f70 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 13:12:30 +0000 Subject: [PATCH 16/17] Updates SUMMARY.md Auto commit by GitBook Editor --- README.md | 4 ++-- SUMMARY.md | 4 ++-- kafka/README.md | 6 ++++++ kafka/introduction.md | 6 ------ rest/README.md | 47 +++++++++++++++++++++++++++++++++++++++++ rest/introduction.md | 49 ------------------------------------------- 6 files changed, 57 insertions(+), 59 deletions(-) create mode 100644 kafka/README.md diff --git a/README.md b/README.md index 25a7b95..e437eae 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ The API Guidelines are split into two main parts: * [General Guidelines](/general-guidelines/README.md) * API type-specific Guidelines - * [REST APIs Guidelines](/rest/introduction.md) - * [Kafka Guidelines](/kafka/introduction.md) + * [REST APIs Guidelines](/rest/README.md) + * [Kafka Guidelines](/kafka/README.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\). diff --git a/SUMMARY.md b/SUMMARY.md index c73448c..ecc82e7 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -18,7 +18,7 @@ ## REST API Guidelines -* [Introduction](rest/introduction.md) +* [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) @@ -66,5 +66,5 @@ ## Kafka Guidelines -* [Introduction](kafka/introduction.md) +* [Introduction](kafka/README.md) diff --git a/kafka/README.md b/kafka/README.md new file mode 100644 index 0000000..9191687 --- /dev/null +++ b/kafka/README.md @@ -0,0 +1,6 @@ +# ![](/assets/adidas-logo.svg) + +# adidas Kafka Guidelines + + + diff --git a/kafka/introduction.md b/kafka/introduction.md index 9191687..e69de29 100644 --- a/kafka/introduction.md +++ b/kafka/introduction.md @@ -1,6 +0,0 @@ -# ![](/assets/adidas-logo.svg) - -# adidas Kafka Guidelines - - - diff --git a/rest/README.md b/rest/README.md index e69de29..b5f7415 100644 --- a/rest/README.md +++ b/rest/README.md @@ -0,0 +1,47 @@ +# ![](/assets/adidas-logo.svg) + +# 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/README.md) + +The REST API Guidelines are further split into the following parts: + +* **Core Principles** + + 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. + + * [**Message level**](https://adidas-group.gitbooks.io/api-guidelines/content/message/) + + The Message guidelines define the structure and semantics of messages used to exchange information. + + * [**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. + + * [**Evolution**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/) + + Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. + + * [**Execution**](https://adidas-group.gitbooks.io/api-guidelines/content/execution/) + + Execution qualities governance, such as security and usability. + +* **Guides** + Guides and materials supporting the REST API Guidelines + +* **API Clients** + + Section dedicated to consumers of adidas APIs + + + diff --git a/rest/introduction.md b/rest/introduction.md index 7c94d44..e69de29 100644 --- a/rest/introduction.md +++ b/rest/introduction.md @@ -1,49 +0,0 @@ -# ![](/assets/adidas-logo.svg) - -# adidas REST API Guidelines - -The adidas REST API Guidelines defines standards and guidelines for building REST APIs at adidas. - -> NOTE: These Guidelines has to be followed in addition to the General Guidelines. - -The REST API Guidelines are further split into the following parts: - -* **Core Principles** - - 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. - - * [**Message level**](https://adidas-group.gitbooks.io/api-guidelines/content/message/) - - The Message guidelines define the structure and semantics of messages used to exchange information. - - * [**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. - - * [**Evolution**](https://adidas-group.gitbooks.io/api-guidelines/content/evolution/) - - Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. - - * [**Execution**](https://adidas-group.gitbooks.io/api-guidelines/content/execution/) - - Execution qualities governance, such as security and usability. - -* **Guides** - Guides and materials supporting the REST API Guidelines - -* **API Clients** - - Section dedicated to consumers of adidas APIs - - - From f59f91074443b0630c4b8950b884af5bbeadc2f1 Mon Sep 17 00:00:00 2001 From: apidesigner Date: Sat, 23 Jun 2018 13:15:06 +0000 Subject: [PATCH 17/17] Deletes kafka/introduction.md Auto commit by GitBook Editor --- kafka/introduction.md | 0 rest/introduction.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 kafka/introduction.md delete mode 100644 rest/introduction.md diff --git a/kafka/introduction.md b/kafka/introduction.md deleted file mode 100644 index e69de29..0000000 diff --git a/rest/introduction.md b/rest/introduction.md deleted file mode 100644 index e69de29..0000000