Merge branch 'master' into naming-conventions

This commit is contained in:
dediejes
2021-02-18 16:43:52 +01:00
73 changed files with 3678 additions and 187 deletions

19
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,19 @@
* **I'm submitting a ...**
- [ ] bug report
- [ ] feature request
- [ ] support request
* **What is the current behavior?**
* **What is the expected behavior?**
* **What is the motivation / use case for changing the behavior?**
* **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

7
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,7 @@
Fixes #
## Proposed Changes
-
-
-

107
.gitignore vendored Normal file
View File

@@ -0,0 +1,107 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# Next.js build output
.next
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# SSHFS
._*

300
.spectral.yml Normal file
View File

@@ -0,0 +1,300 @@
extends: ["spectral:oas"]
rules:
# ---------------------------------------------------------------------------
# General OAS rules
# ---------------------------------------------------------------------------
operation-operationId: false
operation-tags: false
operation-2xx-response: error
adidas-paths-kebab-case:
description: All YAML/JSON paths MUST follow kebab-case
severity: warn
recommended: true
message: "{{property}} is not kebab-case: {{error}}"
given: $.paths[*]~
then:
function: pattern
functionOptions:
match: "^\/([a-z0-9]+(-[a-z0-9]+)*)?(\/[a-z0-9]+(-[a-z0-9]+)*|\/{.+})*$" # doesn't allow /asasd{asdas}sadas pattern or not closed braces
adidas-path-parameters-camelCase-alphanumeric:
description: Path parameters MUST follow camelCase
severity: warn
recommended: true
message: "{{property}} path parameter is not camelCase: {{error}}"
given: $..parameters[?(@.in == 'path')].name
then:
function: pattern
functionOptions:
match: "^[a-z][a-zA-Z0-9]+$"
adidas-definitions-camelCase-alphanumeric:
description: All YAML/JSON definitions MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`.
severity: error
recommended: true
message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`."
given: $.definitions[*]~
then:
function: pattern
functionOptions:
match: "/^[a-z$_]{1}[A-Z09$_]*/"
adidas-properties-camelCase-alphanumeric:
description: All JSON Schema properties MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`.
severity: error
recommended: true
message: "{{property}} MUST follow camelCase and be ASCII alphanumeric characters or `_` or `$`."
given: $.definitions..properties[*]~
then:
function: pattern
functionOptions:
match: "/^[a-z$_]{1}[A-Z09$_]*/"
adidas-request-GET-no-body:
description: "A 'GET' request MUST NOT accept a 'body` parameter"
severity: error
given: $.paths..get.parameters..in
then:
function: pattern
functionOptions:
notMatch: "/^body$/"
adidas-headers-no-x-headers:
description: "All 'HTTP' headers SHOULD NOT include 'X-' headers (https://tools.ietf.org/html/rfc6648)."
severity: warn
given: "$..parameters[?(@.in == 'header')].name"
message: "HTTP headers SHOULD NOT include 'X-' prefix."
recommended: true
type: style
then:
function: pattern
functionOptions:
notMatch: "/^(x|X)-/"
adidas-headers-hyphenated-pascal-case:
description: All `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation
severity: error
given: "$..parameters[?(@.in == 'header')].name"
message: "'HTTP' headers MUST follow 'Hyphenated-Pascal-Case' notation"
recommended: true
type: style
then:
function: pattern
functionOptions:
match: "/^([A-Z][a-z0-9]-)*([A-Z][a-z0-9])+/"
# ---------------------------------------------------------------------------
# Only OAS2 rules
# ---------------------------------------------------------------------------
adidas-oas2-protocol-https-only:
description: "ALL requests MUST go through `https` protocol only"
formats:
- oas2
recommended: true
severity: error
type: "style"
message: "Schemes MUST be https and no other value is allowed."
given: $
then:
field: schemes
function: schema
functionOptions:
schema:
type: array
items:
type: string
enum: ["https"]
maxItems: 1
adidas-oas2-request-support-json:
description: Every request SHOULD support `application/json` media type
formats:
- oas2
severity: warn
message: "{{description}}: {{error}}"
recommended: true
given: "$..consumes"
then:
function: schema
functionOptions:
schema:
type: array
contains:
type: string
enum:
- application/json
adidas-oas2-example-exists-in-parameters:
description: All models MUST have a valid example.
severity: error
recommended: true
formats:
- oas2
message: "{{ property }} MUST have a valid example."
given: "$..parameters..[?(@.in == 'body' && (@.example || @.schema.$ref))]"
then:
function: truthy
# example-exists-in-definitions:
# description: All models MUST have a valid example.
# severity: error
# recommended: true
# formats:
# - oas2
# message: "{{ property }} MUST have a valid example."
# given: "$..definitions..[?(!@.example || !@..$ref)]"
# then:
# function: falsy
# "$..parameters..[?(@.in == 'body')]..[?(@property !== 'properties' && @.example && ( @.type || @.format || @.$ref ))]"
adidas-oas2-response-success-hal: # schemes and/or produces
description: "All success responses MUST be of media type `application/hal+json`"
severity: error
given: $.paths..responses[?( @property >= 200 && @property < 300 && @property != 204)]
recommended: true
type: "style"
formats:
- oas2
message: "Response documents MUST follow application/hal+json: {{error}}"
then:
field: schema
function: schema
functionOptions:
schema:
$ref: "./supermodel/adidas/api/HAL.yaml"
adidas-oas2-response-error-problem: # schemas and/or produces
description: All error responses MUST be of media type `application/problem+json`
severity: error
formats:
- oas2
given: $.paths..responses[?( @property >= 400 && @property < 600 )]
recommended: true
type: "style"
message: "Error response document MUST follow application/problem+json: {{error}}"
then:
field: schema.example
function: schema
functionOptions:
schema:
$ref: "./supermodel/adidas/api/ProblemDetail.yaml"
# ---------------------------------------------------------------------------
# Only OAS3 rules
# ---------------------------------------------------------------------------
adidas-oas3-request-support-json:
description: Every request MUST support `application/json` media type
formats:
- oas3
recommended: true
severity: error
message: "{{description}}: {{error}}"
given: $.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^
then:
function: falsy
adidas-oas3-valid-example-in-parameters:
description: Examples must be valid against their defined schema.
message: "{{error}}"
recommended: true
formats:
- oas3
severity: 0
type: validation
given: "$..parameters..[?(@.in == 'body')]..[?(@property !== 'properties' && @.example
&& ( @.type || @.format || @.$ref ))]"
then:
function: schemaPath
functionOptions:
field: example
schemaPath: "$"
adidas-oas3-valid-example-in-definitions:
description: Examples must be valid against their defined schema.
message: "{{error}}"
recommended: true
formats:
- oas3
severity: 0
type: validation
given: "$..definitions..[?(@property !== 'properties' && @.example && (@.type ||
@.format || @.$ref))]"
then:
function: schemaPath
functionOptions:
field: example
schemaPath: "$"
adidas-oas3-protocol-https-only: # checks how does the servers array values start
description: "ALL requests MUST go through `https` protocol only"
formats:
- oas3
recommended: true
severity: error
message: "Servers MUST be https and no other protocol is allowed."
given: $.servers..url
then:
function: pattern
functionOptions:
match: "/^https:/"
adidas-oas3-response-success-hal:
description: "All success responses MUST be of media type `application/hal+json`"
severity: error
given: $.paths..responses[?( @property >= 200 && @property < 300 && @property != 204)].content[*]~
recommended: true
# type: "style"
formats:
- oas3
message: "Response documents MUST be of application/hal+json media type: {{error}}"
then:
function: enumeration
functionOptions:
values:
- application/hal+json
adidas-oas3-response-success-hal-body: # schemes and/or produces
description: "All success responses MUST follow `application/hal+json` schema"
severity: error
given: $.paths..responses[?( @property >= 200 && @property < 300 && @property != 204)].content[?(@property === "application/hal+json")]
recommended: true
type: "style"
formats:
- oas3
message: "Response documents MUST follow application/hal+json schema: {{error}}"
then:
field: schema
function: schema
functionOptions:
schema:
$ref: "./supermodel/adidas/api/HAL.yaml"
# ---------------------------------------------------------------------------
# Not implemented
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
# Other rules which are redundant or not feasible
# ---------------------------------------------------------------------------
# fields-date-iso8601:
# description: Date and time MUST follow [`ISO 8601` standard](https://www.iso.org/iso-8601-date-and-time-format.html)
# severity: error
# fields-language-iso639:
# description: Language codes MUST follow [`ISO 639` standard](https://www.iso.org/iso-639-language-codes.html)
# severity: error
# fields-country-iso3166:
# description: Country codes MUST follow [`ISO 3166 alpha-2` standard](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
# severity: error
# fields-currency-iso4217:
# description: Currency codes MUST follow [`ISO 4217` standard](https://en.wikipedia.org/wiki/ISO_4217)
# severity: error
# response-303-async-link-header:
# description: A successful and finished async api request returns `303` response code and sends the target resource location in the `Link` header
# severity: hint

View File

@@ -6,6 +6,8 @@ description: Guidelines for the API design and development at adidas
![adidas logo](https://adidas-group.gitbooks.io/api-guidelines/content/assets/adidas-logo.svg) ![adidas logo](https://adidas-group.gitbooks.io/api-guidelines/content/assets/adidas-logo.svg)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[Read online at GitBook](https://adidas.gitbook.io/api-guidelines/) [Read online at GitBook](https://adidas.gitbook.io/api-guidelines/)
### Motivation ### Motivation
@@ -39,9 +41,27 @@ The CAPITALIZED words throughout these guidelines have a special meaning:
Refer to [RFC2119](https://www.ietf.org/rfc/rfc2119) for details. Refer to [RFC2119](https://www.ietf.org/rfc/rfc2119) for details.
### Validating your API Guidelines against OpenAPI Specification
In the `ruleset.md` file you can find a digest of API Guidelines rules which you can validating your API description documents with. If you are using OpenAPI Specification as the API description format you can also leverage the `.spectral.yaml` ruleset to automatically verify your specification compliance using [Spectral](github.com/stoplightio/spectral).
To install Spectral you will need Node.js and a package manager (npm or yarn).
```
npm install -g @stoplight/spectral
# OR
yarn global add @stoplight/spectral
```
Once installed, to verify your OAS file with spectral execute `spectral lint <oas-file> -r <adidas-api-guidelines-folder>/.spectral.yaml` where `<adidas-api-guidelines-folder>/.spectral.yaml` indicated the location `.spectral.yaml` file.
For further documentation on Spectral refer to their [documentation](https://stoplight.io/p/docs/gh/stoplightio/spectral/README.md).
### 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), [_andrzej.jarzyna@adidas.com_](mailto:andrzej.jarzyna@adidas.com) or [_samir.amzani@adidas.com_](mailto:samir.amzani@adidas.com) _in case of questions._
## Intended Use Cases ## Intended Use Cases

View File

@@ -19,43 +19,41 @@
* [Introduction](rest-api-guidelines/rest.md) * [Introduction](rest-api-guidelines/rest.md)
* [Core Principles](rest-api-guidelines/core-principles/README.md) * [Core Principles](rest-api-guidelines/core-principles/README.md)
* [OpenAPI Specification](rest-api-guidelines/core-principles/openapi-specification.md) * [OpenAPI Specification](rest-api-guidelines/core-principles/openapi-specification.md)
* [API Design Platform](rest-api-guidelines/core-principles/apiary.md) * [API Design Platform](rest-api-guidelines/core-principles/design-platform.md)
* [Design Maturity](rest-api-guidelines/core-principles/design-maturity.md) * [Design Maturity](rest-api-guidelines/core-principles/design-maturity.md)
* [Testing](rest-api-guidelines/core-principles/testing.md) * [Testing](rest-api-guidelines/core-principles/testing.md)
* [Functionality](rest-api-guidelines/functionality/README.md) * [Protocol](rest-api-guidelines/protocol/README.md)
* [Protocol](rest-api-guidelines/functionality/protocol/README.md) * [HTTP](rest-api-guidelines/protocol/http.md)
* [HTTP](rest-api-guidelines/functionality/protocol/http.md) * [TLS](rest-api-guidelines/protocol/tls.md)
* [TLS](rest-api-guidelines/functionality/protocol/tls.md) * [Separate Concerns](rest-api-guidelines/protocol/separate-concerns.md)
* [Separate Concerns](rest-api-guidelines/functionality/protocol/separate-concerns.md) * [Request Methods](rest-api-guidelines/protocol/use-appropriate-methods.md)
* [Request Methods](rest-api-guidelines/functionality/protocol/use-appropriate-methods.md) * [Status Codes](rest-api-guidelines/protocol/use-appropriate-status-codes.md)
* [Status Codes](rest-api-guidelines/functionality/protocol/use-appropriate-status-codes.md) * [Message](rest-api-guidelines/message/README.md)
* [Message](rest-api-guidelines/functionality/message/README.md) * [Message Formats](rest-api-guidelines/message/message-formats.md)
* [Message Formats](rest-api-guidelines/functionality/message/message-formats.md) * [Content Negotiation](rest-api-guidelines/message/content-negotiation.md)
* [Content Negotiation](rest-api-guidelines/functionality/message/content-negotiation.md) * [HAL](rest-api-guidelines/message/hal.md)
* [HAL](rest-api-guidelines/functionality/message/hal.md) * [Problem Detail](rest-api-guidelines/message/error-reporting.md)
* [Problem Detail](rest-api-guidelines/functionality/message/error-reporting.md) * [Foreign Key Relations](rest-api-guidelines/message/foreign-key-relations.md)
* [Foreign Key Relations](rest-api-guidelines/functionality/message/foreign-key-relations.md) * [Application](rest-api-guidelines/application/README.md)
* [Application](rest-api-guidelines/functionality/application/README.md) * [Corporate Data Model](rest-api-guidelines/application/harmonize-data.md)
* [Corporate Data Model](rest-api-guidelines/functionality/application/harmonize-data.md) * [Common Data Types](rest-api-guidelines/application/common-data-types.md)
* [Common Data Types](rest-api-guidelines/functionality/application/common-data-types.md) * [Execution](rest-api-guidelines/execution/README.md)
* [Quality](rest-api-guidelines/quality/README.md) * [Pagination](rest-api-guidelines/execution/pagination.md)
* [Execution](rest-api-guidelines/quality/execution/README.md) * [Asynchronous Tasks](rest-api-guidelines/execution/asynchronous-tasks.md)
* [Pagination](rest-api-guidelines/quality/execution/pagination.md) * [Batch Operations](rest-api-guidelines/execution/batch-operations.md)
* [Asynchronous Tasks](rest-api-guidelines/quality/execution/asynchronous-tasks.md) * [Search Requests](rest-api-guidelines/execution/search-requests.md)
* [Batch Operations](rest-api-guidelines/quality/execution/batch-operations.md) * [Query Requests with Large Inputs](rest-api-guidelines/execution/query-requests-with-large-inputs.md)
* [Search Requests](rest-api-guidelines/quality/execution/search-requests.md) * [Choosing Fields and Embedded Resources](rest-api-guidelines/execution/choosing-fields-and-embedded-resoruces.md)
* [Query Requests with Large Inputs](rest-api-guidelines/quality/execution/query-requests-with-large-inputs.md) * [Localization](rest-api-guidelines/execution/localization.md)
* [Choosing Fields and Embedded Resources](rest-api-guidelines/quality/execution/choosing-fields-and-embedded-resoruces.md) * [Rate Limiting](rest-api-guidelines/execution/rate-limiting.md)
* [Localization](rest-api-guidelines/quality/execution/localization.md) * [Caching](rest-api-guidelines/execution/caching.md)
* [Rate Limiting](rest-api-guidelines/quality/execution/rate-limiting.md) * [Testing Enviroments](rest-api-guidelines/execution/testing-enviroments.md)
* [Caching](rest-api-guidelines/quality/execution/caching.md) * [Evolution](rest-api-guidelines/evolution/README.md)
* [Testing Enviroments](rest-api-guidelines/quality/execution/testing-enviroments.md) * [Naming Conventions](rest-api-guidelines/evolution/naming-conventions.md)
* [Evolution](rest-api-guidelines/quality/evolution/README.md) * [Reserved Identifiers](rest-api-guidelines/evolution/reserved-identifiers.md)
* [Naming Conventions](rest-api-guidelines/quality/evolution/naming-conventions.md) * [URI Structure](rest-api-guidelines/evolution/uri-structure.md)
* [Reserved Identifiers](rest-api-guidelines/quality/evolution/reserved-identifiers.md) * [Changes and Versioning](rest-api-guidelines/evolution/versioning.md)
* [URI Structure](rest-api-guidelines/quality/evolution/uri-structure.md) * [Phasing out Old Versions](rest-api-guidelines/evolution/phasing-out-old-versions.md)
* [Changes and Versioning](rest-api-guidelines/quality/evolution/versioning.md)
* [Phasing out Old Versions](rest-api-guidelines/quality/evolution/phasing-out-old-versions.md)
* [Guides](rest-api-guidelines/guides/README.md) * [Guides](rest-api-guidelines/guides/README.md)
* [API Testing CI Environment](rest-api-guidelines/guides/api-testing-ci-environment.md) * [API Testing CI Environment](rest-api-guidelines/guides/api-testing-ci-environment.md)
* [Complete API Development](rest-api-guidelines/guides/complete-api-development.md) * [Complete API Development](rest-api-guidelines/guides/complete-api-development.md)

View File

@@ -13,5 +13,5 @@ This work is partly based on the work of many talented individuals and exception
* [Facebook Graph API Team](https://developers.facebook.com/docs/graph-api/) * [Facebook Graph API Team](https://developers.facebook.com/docs/graph-api/)
* [Subbu Allamaraju: RESTFul Web Services Cookbook](http://shop.oreilly.com/product/9780596801694.do) * [Subbu Allamaraju: RESTFul Web Services Cookbook](http://shop.oreilly.com/product/9780596801694.do)
* [Paolo De Lucia](https://www.linkedin.com/in/paolodelucia/) * [Paolo De Lucia](https://www.linkedin.com/in/paolodelucia/)
* [Jakub Rożek](https://github.com/P0lip)
* [Phil Sturgeon](https://github.com/philsturgeon)

View File

@@ -0,0 +1,167 @@
openapi: "3.0.0"
info:
title: Simple API overview
version: 2.0.0
paths:
/:
get:
operationId: listVersionsv2
summary: List API versions
responses:
'200':
description: |-
200 response
content:
application/json:
examples:
foo:
value: {
"versions": [
{
"status": "CURRENT",
"updated": "2011-01-21T11:33:21Z",
"id": "v2.0",
"links": [
{
"href": "http://127.0.0.1:8774/v2/",
"rel": "self"
}
]
},
{
"status": "EXPERIMENTAL",
"updated": "2013-07-23T11:33:21Z",
"id": "v3.0",
"links": [
{
"href": "http://127.0.0.1:8774/v3/",
"rel": "self"
}
]
}
]
}
'300':
description: |-
300 response
content:
application/json:
examples:
foo:
value: |
{
"versions": [
{
"status": "CURRENT",
"updated": "2011-01-21T11:33:21Z",
"id": "v2.0",
"links": [
{
"href": "http://127.0.0.1:8774/v2/",
"rel": "self"
}
]
},
{
"status": "EXPERIMENTAL",
"updated": "2013-07-23T11:33:21Z",
"id": "v3.0",
"links": [
{
"href": "http://127.0.0.1:8774/v3/",
"rel": "self"
}
]
}
]
}
/v2:
get:
operationId: getVersionDetailsv2
summary: Show API version details
responses:
'200':
description: |-
200 response
content:
application/json:
examples:
foo:
value: {
"version": {
"status": "CURRENT",
"updated": "2011-01-21T11:33:21Z",
"media-types": [
{
"base": "application/xml",
"type": "application/vnd.openstack.compute+xml;version=2"
},
{
"base": "application/json",
"type": "application/vnd.openstack.compute+json;version=2"
}
],
"id": "v2.0",
"links": [
{
"href": "http://127.0.0.1:8774/v2/",
"rel": "self"
},
{
"href": "http://docs.openstack.org/api/openstack-compute/2/os-compute-devguide-2.pdf",
"type": "application/pdf",
"rel": "describedby"
},
{
"href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl",
"type": "application/vnd.sun.wadl+xml",
"rel": "describedby"
},
{
"href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl",
"type": "application/vnd.sun.wadl+xml",
"rel": "describedby"
}
]
}
}
'203':
description: |-
203 response
content:
application/json:
examples:
foo:
value: {
"version": {
"status": "CURRENT",
"updated": "2011-01-21T11:33:21Z",
"media-types": [
{
"base": "application/xml",
"type": "application/vnd.openstack.compute+xml;version=2"
},
{
"base": "application/json",
"type": "application/vnd.openstack.compute+json;version=2"
}
],
"id": "v2.0",
"links": [
{
"href": "http://23.253.228.211:8774/v2/",
"rel": "self"
},
{
"href": "http://docs.openstack.org/api/openstack-compute/2/os-compute-devguide-2.pdf",
"type": "application/pdf",
"rel": "describedby"
},
{
"href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl",
"type": "application/vnd.sun.wadl+xml",
"rel": "describedby"
}
]
}
}

View File

@@ -0,0 +1,203 @@
openapi: 3.0.0
info:
title: Link Example
version: 1.0.0
paths:
/2.0/users/{username}:
get:
operationId: getUserByName
parameters:
- name: username
in: path
required: true
schema:
type: string
responses:
'200':
description: The User
content:
application/json:
schema:
$ref: '#/components/schemas/user'
links:
userRepositories:
$ref: '#/components/links/UserRepositories'
/2.0/repositories/{username}:
get:
operationId: getRepositoriesByOwner
parameters:
- name: username
in: path
required: true
schema:
type: string
responses:
'200':
description: repositories owned by the supplied user
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/repository'
links:
userRepository:
$ref: '#/components/links/UserRepository'
/2.0/repositories/{username}/{slug}:
get:
operationId: getRepository
parameters:
- name: username
in: path
required: true
schema:
type: string
- name: slug
in: path
required: true
schema:
type: string
responses:
'200':
description: The repository
content:
application/json:
schema:
$ref: '#/components/schemas/repository'
links:
repositoryPullRequests:
$ref: '#/components/links/RepositoryPullRequests'
/2.0/repositories/{username}/{slug}/pullrequests:
get:
operationId: getPullRequestsByRepository
parameters:
- name: username
in: path
required: true
schema:
type: string
- name: slug
in: path
required: true
schema:
type: string
- name: state
in: query
schema:
type: string
enum:
- open
- merged
- declined
responses:
'200':
description: an array of pull request objects
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/pullrequest'
/2.0/repositories/{username}/{slug}/pullrequests/{pid}:
get:
operationId: getPullRequestsById
parameters:
- name: username
in: path
required: true
schema:
type: string
- name: slug
in: path
required: true
schema:
type: string
- name: pid
in: path
required: true
schema:
type: string
responses:
'200':
description: a pull request object
content:
application/json:
schema:
$ref: '#/components/schemas/pullrequest'
links:
pullRequestMerge:
$ref: '#/components/links/PullRequestMerge'
/2.0/repositories/{username}/{slug}/pullrequests/{pid}/merge:
post:
operationId: mergePullRequest
parameters:
- name: username
in: path
required: true
schema:
type: string
- name: slug
in: path
required: true
schema:
type: string
- name: pid
in: path
required: true
schema:
type: string
responses:
'204':
description: the PR was successfully merged
components:
links:
UserRepositories:
# returns array of '#/components/schemas/repository'
operationId: getRepositoriesByOwner
parameters:
username: $response.body#/username
UserRepository:
# returns '#/components/schemas/repository'
operationId: getRepository
parameters:
username: $response.body#/owner/username
slug: $response.body#/slug
RepositoryPullRequests:
# returns '#/components/schemas/pullrequest'
operationId: getPullRequestsByRepository
parameters:
username: $response.body#/owner/username
slug: $response.body#/slug
PullRequestMerge:
# executes /2.0/repositories/{username}/{slug}/pullrequests/{pid}/merge
operationId: mergePullRequest
parameters:
username: $response.body#/author/username
slug: $response.body#/repository/slug
pid: $response.body#/id
schemas:
user:
type: object
properties:
username:
type: string
uuid:
type: string
repository:
type: object
properties:
slug:
type: string
owner:
$ref: '#/components/schemas/user'
pullrequest:
type: object
properties:
id:
type: integer
title:
type: string
repository:
$ref: '#/components/schemas/repository'
author:
$ref: '#/components/schemas/user'

View File

@@ -0,0 +1,158 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
description: A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.0 specification
termsOfService: http://swagger.io/terms/
contact:
name: Swagger API Team
email: apiteam@swagger.io
url: http://swagger.io
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
- url: http://petstore.swagger.io/api
paths:
/pets:
get:
description: |
Returns all pets from the system that the user has access to
Nam sed condimentum est. Maecenas tempor sagittis sapien, nec rhoncus sem sagittis sit amet. Aenean at gravida augue, ac iaculis sem. Curabitur odio lorem, ornare eget elementum nec, cursus id lectus. Duis mi turpis, pulvinar ac eros ac, tincidunt varius justo. In hac habitasse platea dictumst. Integer at adipiscing ante, a sagittis ligula. Aenean pharetra tempor ante molestie imperdiet. Vivamus id aliquam diam. Cras quis velit non tortor eleifend sagittis. Praesent at enim pharetra urna volutpat venenatis eget eget mauris. In eleifend fermentum facilisis. Praesent enim enim, gravida ac sodales sed, placerat id erat. Suspendisse lacus dolor, consectetur non augue vel, vehicula interdum libero. Morbi euismod sagittis libero sed lacinia.
Sed tempus felis lobortis leo pulvinar rutrum. Nam mattis velit nisl, eu condimentum ligula luctus nec. Phasellus semper velit eget aliquet faucibus. In a mattis elit. Phasellus vel urna viverra, condimentum lorem id, rhoncus nibh. Ut pellentesque posuere elementum. Sed a varius odio. Morbi rhoncus ligula libero, vel eleifend nunc tristique vitae. Fusce et sem dui. Aenean nec scelerisque tortor. Fusce malesuada accumsan magna vel tempus. Quisque mollis felis eu dolor tristique, sit amet auctor felis gravida. Sed libero lorem, molestie sed nisl in, accumsan tempor nisi. Fusce sollicitudin massa ut lacinia mattis. Sed vel eleifend lorem. Pellentesque vitae felis pretium, pulvinar elit eu, euismod sapien.
operationId: findPets
parameters:
- name: tags
in: query
description: tags to filter by
required: false
style: form
schema:
type: array
items:
type: string
- name: limit
in: query
description: maximum number of results to return
required: false
schema:
type: integer
format: int32
responses:
'200':
description: pet response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
default:
description: unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
post:
description: Creates a new pet in the store. Duplicates are allowed
operationId: addPet
requestBody:
description: Pet to add to the store
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/NewPet'
responses:
'200':
description: pet response
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
default:
description: unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/pets/{id}:
get:
description: Returns a user based on a single ID, if the user does not have access to the pet
operationId: find pet by id
parameters:
- name: id
in: path
description: ID of pet to fetch
required: true
schema:
type: integer
format: int64
responses:
'200':
description: pet response
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
default:
description: unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
delete:
description: deletes a single pet based on the ID supplied
operationId: deletePet
parameters:
- name: id
in: path
description: ID of pet to delete
required: true
schema:
type: integer
format: int64
responses:
'204':
description: pet deleted
default:
description: unexpected error
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
Pet:
allOf:
- $ref: '#/components/schemas/NewPet'
- type: object
required:
- id
properties:
id:
type: integer
format: int64
NewPet:
type: object
required:
- name
properties:
name:
type: string
tag:
type: string
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string

View File

@@ -0,0 +1,365 @@
swagger: '2.0'
info:
version: '3.0.0'
title: '[Demo] Orders API'
contact:
name: Z
email: "z@goodapi.co"
description: |
Sample API conforming to [adidas API Guidelines](https://adidas.gitbook.io/api-guidelines/).
produces:
- application/hal+json # Representation message format
- application/problem+json # Error message format
schemes:
- https
host: "example.com"
securityDefinitions:
'API Key':
type: apiKey
in: header
name: x-api-key
security:
- "API Key": []
paths:
/:
x-summary: API Root
get:
summary: Retrieve API Root
description: The API Root contains the initial set of link relations.
responses:
200:
description: The root of the API
schema:
allOf:
- $ref: '#/definitions/supermodelIoAdidasApiHAL'
example:
_links:
self:
href: /
orders:
href: /orders
/orders:
x-summary: List of Orders
get:
summary: Retrieve List of Orders
description: Retrieves a list of orders with pagination.
parameters:
- $ref: '#/parameters/offset'
- $ref: '#/parameters/limit'
responses:
200:
description: The list of Orders
schema:
$ref: '#/definitions/supermodelIoAdidasExamplesOrderApiOrders'
post:
summary: Create a New Order
description: Creates a new order.
consumes:
- application/json
parameters:
- name: Order
in: body
description: Order to be created
required: true
schema:
$ref: '#/definitions/supermodelIoAdidasExamplesOrderOrder'
responses:
201:
description: Newly created order
schema:
$ref: '#/definitions/supermodelIoAdidasExamplesOrderApiOrder'
/orders/{orderId}:
x-summary: Order
parameters:
- name: orderId
in: path
description: Id of the Order
required: true
type: string
x-example: '1234'
get:
summary: Retrieve Order
description: Retrieves an order with specified fields.
parameters:
- $ref: '#/parameters/fields'
responses:
200:
description: A particular Order
schema:
$ref: '#/definitions/supermodelIoAdidasExamplesOrderApiOrder'
404:
description: The request Order wasn't found
headers:
Content-Type:
type: string
default: application/problem+json
schema:
allOf:
- $ref: '#/definitions/supermodelIoAdidasApiProblemDetail'
example:
title: 'Not Found'
detail: 'Cannot find the requested order'
status: 404
instance: '/orders/1234'
patch:
summary: Update Order
description: Does a partial update of an order.
consumes:
- application/json
parameters:
- name: Order
in: body
description: Partial order update
required: true
schema:
$ref: '#/definitions/supermodelIoAdidasExamplesOrderApiOrderPatch'
responses:
200:
description: The Order was updated
schema:
$ref: '#/definitions/supermodelIoAdidasExamplesOrderApiOrder'
delete:
summary: Delete Order
description: Deletes an order without returning its instance.
produces: []
responses:
204:
description: The Order was deleted
parameters:
# adidas API guidelines: Pagination
offset:
name: offset
in: query
description: Number of results to skip from the start of the list
required: false
type: string
default: '0'
x-example: '10'
# adidas API guidelines: Pagination
limit:
name: limit
in: query
description: The maximum number of reusults to return
required: false
type: string
default: '10'
x-example: '5'
# adidas API guidelines: Sparse fieldset
fields:
name: fields
in: query
description: Comma-separated list of fields to include in the response
required: false
type: array
items:
type: string
collectionFormat: csv
x-example:
- articleNumber
- modelNumber
# adidas API guidelines: Sparse fieldset
embedded:
name: embedded
in: query
description: Comma-separated list of resource (relations) to embed in the response
required: false
type: array
items:
type: string
collectionFormat: csv
x-example:
- prices
- assets
# DO NOT EDIT
# This definitions section is automatically generated by supermodel.io
#
# http://supermodel.io
# https://github.com/supermodel/supermodel-cli
definitions:
supermodelIoAdidasExamplesOrderApiOrder:
title: Order HAL Representation
type: object
allOf:
- $ref: '#/definitions/supermodelIoAdidasApiHAL'
- $ref: '#/definitions/supermodelIoAdidasExamplesOrderOrder'
example:
_links:
self:
href: /orders/1234
edit:
href: /orders/1234
delete:
href: /orders/1234
profile:
href: 'https://adidas-group.com/gdm/OMS'
orderNumber: 1234
itemCount: 42
status: pending
supermodelIoAdidasExamplesOrderApiOrderPatch:
title: OrderPatch
description: OrderPatch model description
type: object
allOf:
- $ref: '#/definitions/supermodelIoAdidasExamplesOrderOrder'
example:
status: cancelled
orderNumber: 1
itemCount: 2
supermodelIoAdidasExamplesOrderApiOrders:
title: Collection of Orders HAL Representation
type: object
allOf:
- $ref: '#/definitions/supermodelIoAdidasApiHAL'
example:
_links:
self:
href: /orders
create:
href: /orders
next:
href: /orders?offset=5&limit=5
first:
href: /orders?offset=0&limit=5
last:
href: /orders?offset=40&limit=5
_embedded:
order:
- _links:
self:
href: /orders/1234
edit:
href: /orders/1234
delete:
href: /orders/1234
profile:
href: 'https://adidas-group.com/gdm/OMS'
orderNumber: 1234
itemCount: 42
status: pending
supermodelIoAdidasExamplesOrderApiProblemDetail:
title: Problem Detail
type: object
allOf:
- $ref: '#/definitions/supermodelIoAdidasApiProblemDetail'
supermodelIoAdidasApiHAL:
title: HAL
description: >-
JSON Hypertext Application Language. Definition of [HAL message
format](https://tools.ietf.org/html/draft-kelly-json-hal-08)
type: object
properties:
_links:
type: object
additionalProperties:
allOf:
- $ref: '#/definitions/supermodelIoAdidasApiHALDefinitionsHalLinkObject'
- type: array
items:
$ref: '#/definitions/supermodelIoAdidasApiHALDefinitionsHalLinkObject'
properties:
curies:
allOf:
- $ref: '#/definitions/supermodelIoAdidasApiHALDefinitionsHalCuriesLink'
- type: array
items:
$ref: >-
#/definitions/supermodelIoAdidasApiHALDefinitionsHalCuriesLink
_embedded:
type: object
additionalProperties:
allOf:
- $ref: '#/definitions/supermodelIoAdidasApiHAL'
- type: array
items:
$ref: '#/definitions/supermodelIoAdidasApiHAL'
supermodelIoAdidasApiHALDefinitionsHalLinkObject:
title: HAL Link Object
type: object
properties:
href:
type: string
templated:
type: boolean
type:
type: string
deprecation:
type: string
name:
type: string
profile:
type: string
title:
type: string
hreflang:
type: string
required:
- href
supermodelIoAdidasApiHALDefinitionsHalCuriesLink:
title: HAL Curies Link
allOf:
- type: object
properties:
templated:
enum:
- true
required:
- templated
- $ref: '#/definitions/supermodelIoAdidasApiHALDefinitionsHalLinkObject'
supermodelIoAdidasExamplesOrderOrder:
title: Order
type: object
description: Order model description
properties:
orderNumber:
type: number
itemCount:
type: number
status:
type: string
required:
- orderNumber
- itemCount
example:
orderNumber: 42
itemCount: 3
status: pending
supermodelIoAdidasApiProblemDetail:
title: Problem Details for HTTP APIs
description: >-
Definition of [RFC7807](https://tools.ietf.org/html/rfc7807) problem
detail
type: object
properties:
type:
type: string
title:
type: string
status:
type: number
detail:
type: string
instance:
type: string
required:
- title
- detail

View File

@@ -2,5 +2,5 @@
Approved API Design, represented by its API Description or schema, **MUST** represent the **contract** between API stakeholder, implementers, and consumers. 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\). An update to the corresponding contract \(API Design\) **MUST** be implemented and approved before any change to an API **MUST**.

View File

@@ -2,7 +2,7 @@
Any JSON-based message **MUST** conform to the following rules: Any JSON-based message **MUST** conform to the following rules:
1. All JSON field names **MUST** follow the [Naming Conventions ](../rest-api-guidelines/quality/evolution/naming-conventions.md)\(`camelCase`, American English, etc.\) 1. All JSON field names **MUST** follow the [Naming Conventions ](../rest-api-guidelines/evolution/naming-conventions.md)\(`camelCase`, American English, etc.\)
2. Field names **MUST** be ASCII alpha num characters, underscore \(`_`\) or dollar sign \(`$`\) 2. Field names **MUST** be ASCII alpha num characters, underscore \(`_`\) or dollar sign \(`$`\)
3. Boolean fields **MUST NOT** be of `null` value 3. Boolean fields **MUST NOT** be of `null` value
4. Fields with `null` value **SHOULD** be omitted 4. Fields with `null` value **SHOULD** be omitted

View File

@@ -0,0 +1,105 @@
# Validating API Description
If you want to follow adidas API design guidelines for REST APIs you MAY validate your OAS file using [Spectral](https://github.com/stoplightio/spectral) and the adidas ruleset file.
## Installing Spectral
To install Spectral you will need Node.js and a package manager (npm or yarn).
```
npm install -g @stoplight/spectral
# OR
yarn global add @stoplight/spectral
```
### Docker
Spectral is also available as a Docker image, which can be handy for all sorts of things, like if you're contributing code to Spectral, want to integrate it into your CI build.
```
docker run --rm -it stoplight/spectral lint "${url}"
```
If the file you want to lint is on your computer, you'll need to mount the directory where the file resides as a volume
```
docker run --rm -it -v $(pwd):/tmp stoplight/spectral lint "/tmp/file.yaml"
```
## Using Spectral
Once installed Spectral, you can validate an OAS file (in YAML or JSON format) according to a given set of rules. Spectral has a predefined set of rules validating OpenAPI 2.x (Swagger) and OpenAPI 3.x files.
Spectral comes with a CLI and can be run from your command line:
```
spectral lint <oas-file>
```
For more details about how to utilize Spectral CLI you can check the CLI built-in help:
```
spectral lint -h
```
or go to the official [Spectral documentation](https://stoplight.io/p/docs/gh/stoplightio/spectral/docs/guides/cli.md).
Spectral can also be used from within JavaScript. For details on how to accomplish this, please refer to the [documentation](https://stoplight.io/p/docs/gh/stoplightio/spectral/docs/guides/javascript.md).
## Validating with Adidas API Guidelines
To check whether your API Specification complies with Adidas API Guidelines you will need the `.spectral.yaml` file from this repository ([here](https://github.com/adidas/api-guidelines/blob/master/.spectral.yml)).
```
spectral lint <oas-file> -r <adidas-api-guidelines-folder>/.spectral.yaml
```
### Validation problems
Spectral defines 4 levels of problem severity:
1. error - the specification either does not pass standard YAML/JSON structure validation, standard OAS2/OAS3 validation or is not compliant with core adidas guidelines.
2. warning - the specification lacks certain important validation check (e.g. `hosts` for OAS2) which are not required, but you should be cautious about them.
3. information - there are some best practices which you did not implement in your specification and should consider doing so.
4. hint - you should be aware that there are some additional best practices which you can consider implementing in your specification.
Currently any problem of severity of error or warning will cause a failure status code of `1`. This means that any `error` or `warning` in your specification will prevent your CI/CD pipeline from succeeding. During design process you may want to ignore certain warnings, such as the runtime information (e.g. `hosts` or `servers`). In order to do that you can add a `--skip-rule` flag:
```
spectral lint my-api-spec.yaml --skip-rule=adidas-oas3-protocol-https-only
```
## Spectral rules list
The documentation on Spectral general OAS and specific rules for OAS2 and OAS3 can be found here: https://github.com/stoplightio/spectral/blob/develop/docs/reference/openapi-rules.md.
Adidas specific rules are listed below:
### Adidas general rules
* `adidas-paths-camelCase` - All YAML/JSON paths MUST follow camelCase.
* `adidas-definitions-camelCase-alphanumeric` - All YAML/JSON definitions MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`.
* `adidas-properties-camelCase-alphanumeric` - All JSON Schema properties MUST follow fields-camelCase and be ASCII alphanumeric characters or `_` or `$`.
* `adidas-request-GET-no-body` - A 'GET' request MUST NOT accept a 'body` parameter.
* `adidas-uri-template-cannot-dash` - The 'URI' template (RFC 6570 - https://tools.ietf.org/html/rfc6570) cannot contain a '-' character.
* `adidas-headers-no-x-headers` - All 'HTTP' headers SHOULD NOT include 'X-' headers (https://tools.ietf.org/html/rfc6648).
* `adidas-headers-hyphenated-pascal-case` - All `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation.
### Adidas OAS2/Swagger rules
* `adidas-oas2-protocol-https-only` - ALL requests MUST go through `https` protocol only.
* `adidas-oas2-request-support-json` - Every request SHOULD support `application/json` media type.
* `adidas-oas2-example-exists-in-parameters` - All models MUST have a valid example.
* `adidas-oas2-response-success-hal` - All success responses MUST be of media type `application/hal+json`.
* `adidas-oas2-response-error-problem` - All error responses MUST be of media type `application/problem+json`.
### Adidas OAS3 rules
* `adidas-oas3-request-support-json` - Every request MUST support `application/json` media type.
* `adidas-oas3-valid-example-in-parameters` - Examples must be valid against their defined schema.
* `adidas-oas3-valid-example-in-definitions` - Examples must be valid against their defined schema.
* `adidas-oas3-protocol-https-only` - ALL requests MUST go through `https` protocol only.
* `adidas-oas3-response-success-hal` - All success responses MUST be of media type `application/hal+json`.
* `adidas-oas3-response-success-hal-body` - All success responses MUST follow `application/hal+json` schema.

17
package.json Normal file
View File

@@ -0,0 +1,17 @@
{
"name": "api-guidelines",
"version": "1.0.0",
"description": "adidas API guidelines",
"repository": "git@github.com:adidas/api-guidelines.git",
"author": "software.engineering@adidas.com",
"license": "MIT",
"private": true,
"dependencies": {
"@stoplight/spectral": "^5.3.0",
"@supermodel/cli": "^0.46.29"
},
"scripts": {
"build-examples": "supermodel schema oas2 supermodel/adidas/examples/order/api/ -o examples/demo-orderapi-v3.oas2.yaml",
"test": "spectral lint examples/valid/*"
}
}

View File

@@ -2,5 +2,5 @@
Every API **SHOULD** use company terms for resource names, relation names and representation message field names. Every API **SHOULD** use company terms for resource names, relation names and representation message field names.
Also, every API **MUST** follow the [naming conventions](../../quality/evolution/naming-conventions.md). Also, every API **MUST** follow the [naming conventions](../evolution/naming-conventions.md).

View File

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

View File

@@ -0,0 +1,12 @@
# API Design Platform
1. [SwaggerHub](https://swagger.io/tools/swaggerhub/) is the primary platform supporting [API first approach](../../general-guidelines/api-first.md). SwaggerHub **SHOULD** be used during API Design.
2. Every API description **MUST** be stored in [SwaggerHub](https://design.api.3stripes.io/) under the adidas team.
3. SwaggerHub **MUST** be the **single source of truth** to learn about existing APIs within the organization.
> NOTE: SwaggerHub supports API-first approach in multiple ways:
> For example, it 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 Design platform
> should be automated (e.g. using CI/CD framework or the Design Platform capabilities).

View File

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

View File

@@ -1,6 +1,18 @@
# Testing # Testing
Every API description \(contract\) using HTTP\(S\) protocol **MUST** be tested against its API implementation. The tests **MUST** be executed using the [Dredd testing framework](https://github.com/apiaryio/dredd). The Dredd **MUST** [report the test results to Apiary](https://help.apiary.io/tools/automated-testing/testing-reporter/). ## DREDD
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).
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. 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.
## PACT
Every adidas **CORE** API **MUST** be tested additionally applying Consumer Driven Contract Testing principles. The tests **MUST** be executed using the [PACT contract testing tool](https://docs.pact.io/). PACT tests **MUST** use adidas [PACT-Broker](http://pact.ati.adidas.com/) to store results and evidences.
In addition to local runs, PACT tests **SHOULD** be an integral part of 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.
Using Consumer Driven Contract Testing with PACT is *not mandatory* for adidas **NON-CORE** APIs, but strongly recommended due to the advantages this approach brings. It will be also a proof of our Software Engineering practices maturity.
More information, guides and seeds about how to use PACT can be found on (internal link)[adidas Consumer Driven Contract Testing guide](https://tools.adidas-group.com/confluence/display/DSBP/adidas+Consumer+Driven+Contract+Testing+guide) page.

View File

@@ -4,8 +4,8 @@ The list of all reserved identifiers or identifiers with special meaning.
## Representation Format Fields ## Representation Format Fields
* `_links` - [HAL](../../functionality/message/hal.md) * `_links` - [HAL](../message/hal.md)
* `_embedded` - [HAL](../../functionality/message/hal.md) * `_embedded` - [HAL](../message/hal.md)
## Query Parameters ## Query Parameters

View File

@@ -13,7 +13,7 @@ Any change to:
4. **Relation** with other resources \(e.g Links\) 4. **Relation** with other resources \(e.g Links\)
5. **Representation format** \(e.g. HTTP request and response bodies\) 5. **Representation format** \(e.g. HTTP request and response bodies\)
**MUST** follow the [**Rules for Extending**](../../../general-guidelines/rules-for-extending.md). **MUST** follow the [**Rules for Extending**](../../general-guidelines/rules-for-extending.md).
## Identifier Stability \(No URI Versioning\) ## Identifier Stability \(No URI Versioning\)
@@ -29,7 +29,7 @@ Adding a new action to existing resource with identifier `/greeting` doesn't cha
## Backward-incompatible Changes ## Backward-incompatible Changes
A change to _resource identifier_, _resource metadata_, _resource actions_ and _resource relations_ that can't follow the [Rules for Extending](../../../general-guidelines/rules-for-extending.md) **MUST** result into a **new resource variant**. Existing resource variant **MUST** be preserved. A change to _resource identifier_, _resource metadata_, _resource actions_ and _resource relations_ that can't follow the [Rules for Extending](../../general-guidelines/rules-for-extending.md) **MUST** result into a **new resource variant**. Existing resource variant **MUST** be preserved.
A change to _representation format_ **SHOULD NOT** result into a new resource variant. A change to _representation format_ **SHOULD NOT** result into a new resource variant.
@@ -41,7 +41,7 @@ Currently, optional URI Query Parameter `first` on an existing resource `/greeti
> 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. > 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](../../functionality/message/content-negotiation.md). If a change can't follow the Rules for Extending the representation format media type **MUST** be changed. If the media type has been changed the previous media type, **MUST** be available via [Content Negotiation](../message/content-negotiation.md).
If the media type conveys the version parameter, the version parameter **SHOULD** follow [Semantic versioning](http://semver.org/). If the media type conveys the version parameter, the version parameter **SHOULD** follow [Semantic versioning](http://semver.org/).
@@ -87,13 +87,6 @@ info:
Has MAJOR version 2, MINOR version 1 and PATCH version 3. 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 #### Recommended Reading
* [Evolving HTTP APIs](https://www.mnot.net/blog/2012/12/04/api-evolution) * [Evolving HTTP APIs](https://www.mnot.net/blog/2012/12/04/api-evolution)

View File

@@ -0,0 +1,105 @@
# 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.
### Example
1. **Initiate the asynchronous task**
```
POST /feeds/tasks/ HTTP/1.1
Content-Type: application/json
...
HTTP/1.1 202 Accepted
Content-Type: application/hal+json
Retry-After: 60
{
"_links": {
"self": { "href": "/feeds/tasks/1" }
},
"message": "Your task to generate feed has been accepted. Try query for result after 60 seconds.",
"retryAfter": 60
}
```
1. **Poll the task status: In progress**
```
GET /feeds/tasks/1 HTTP/1.1
...
HTTP/1.1 200 Ok
Content-Type: application/hal+json
Retry-After: 30
{
"_links": {
"self": { "href": "/feeds/tasks/1" }
},
"message": "Your feed is being generated. Try query for result after 30 seconds.",
"retryAfter": 30
}
```
1. **Poll the task status: Finished**
```
GET /feeds/tasks/1 HTTP/1.1
...
HTTP/1.1 303 See Other
Location: /feeds/1
Content-Location: /feeds/tasks/1
Content-Type: application/hal+json
{
"_links": {
"self": { "href": "/feeds/tasks/1" },
"feed": { "href": "/feeds/1" }
},
"message": "Your feed is ready."
}
```
1. **Poll the task status: Failure**
```
GET /feeds/tasks/1 HTTP/1.1
...
HTTP/1.1 200 OK
Content-Type: application/problem+json
{
"title": "Wrong input parameters",
"detail: "Missing required input parameter XYZ.",
"status": 400
}
```

View File

@@ -70,7 +70,7 @@ However, in such an operation has to be provided such a non-atomic bulk operatio
1. Non-atomic bulk operation **MUST** return a success status code \(e.g. **200 OK**\) only if every and all sub-operation succeeded. 1. Non-atomic bulk operation **MUST** return a success status code \(e.g. **200 OK**\) only if every and all sub-operation succeeded.
2. If any single one sub-operation fails the whole non-atomic bulk operation **MUST** return the respective **4xx** or **5xx** status code. 2. If any single one sub-operation fails the whole non-atomic bulk operation **MUST** return the respective **4xx** or **5xx** status code.
3. In the case of a failure the response **MUST** contain the [problem detail](../../functionality/message/message-formats.md#error-response-format) information about every sub-operation that has failed. 3. In the case of a failure the response **MUST** contain the [problem detail](../message/message-formats.md#error-response-format) information about every sub-operation that has failed.
4. **The client MUST be aware that the operation is non-atomic and the even the operation might have failed some sub-operations were processed successfully.** 4. **The client MUST be aware that the operation is non-atomic and the even the operation might have failed some sub-operations were processed successfully.**
### Example ### Example

View File

@@ -15,7 +15,7 @@ The Collection of Orders using the collection navigation link and `offset` and `
"first": { "href": "/orders?limit=10" }, "first": { "href": "/orders?limit=10" },
"last": { "href": "/orders?offset=900&limit=10" } "last": { "href": "/orders?offset=900&limit=10" }
}, },
"total_count": 910, "totalCount": 910,
"_embedded": { "_embedded": {
"order": [ "order": [
{ ... }, { ... },

View File

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

View File

@@ -0,0 +1,81 @@
openapi: 3.0.0
info:
title: HAL
description: 'HAL snippet for OAS3'
contact:
name: Andrzej Jarzyna
url: https://github.com/jerzyn
email: andrzej.jarzyna@adidas.com
version: '1.0.0'
servers:
- url: http://{defaultHost}
variables:
defaultHost:
default: www.example.com
paths: {}
components:
schemas:
HALLinkObject:
title: HALLinkObject
required:
- href
type: object
properties:
href:
type: string
templated:
type: boolean
type:
type: string
deprecation:
type: string
name:
type: string
profile:
type: string
title:
type: string
hreflang:
type: string
HALCuriesLink:
title: HALCuriesLink
required:
- templated
- href
type: object
properties:
templated:
type: string
example: True
href:
type: string
type:
type: string
deprecation:
type: string
name:
type: string
profile:
type: string
title:
type: string
hreflang:
type: string
HAL:
title: HAL
type: object
properties:
_links:
$ref: '#/components/schemas/Links'
_embedded:
type: object
additionalProperties:
$ref: '#/components/schemas/HAL'
description: JSON Hypertext Application Language. Definition of [HAL message format](https://tools.ietf.org/html/draft-kelly-json-hal-08)
Links:
title: Links
type: object
properties:
curies:
$ref: '#/components/schemas/HALCuriesLink'
tags: []

View File

@@ -0,0 +1,74 @@
swagger: "2.0"
info:
title: HAL
description: HAL snippet for OAS2
version: 1.0.0
host: api.example.com
basePath: /v1
schemes:
- https
paths: {}
definitions:
HalLinkObject:
title: HAL Link Object
type: object
properties:
href:
type: string
templated:
type: boolean
type:
type: string
deprecation:
type: string
name:
type: string
profile:
type: string
title:
type: string
hreflang:
type: string
required:
- href
HalCuriesLink:
title: HAL Curies Link
allOf:
- type: object
properties:
templated:
enum:
- true
required:
- templated
- $ref: '#/definitions/HalLinkObject'
HAL:
title: HAL
description: >-
JSON Hypertext Application Language. Definition of [HAL message
format](https://tools.ietf.org/html/draft-kelly-json-hal-08)
type: object
properties:
_links:
type: object
additionalProperties:
allOf:
- $ref: '#/definitions/HalLinkObject'
- type: array
items:
$ref: '#/definitions/HalLinkObject'
properties:
curies:
allOf:
- $ref: '#/definitions/HalCuriesLink'
- type: array
items:
$ref: '#/definitions/HalCuriesLink'
_embedded:
type: object
additionalProperties:
allOf:
- $ref: '#/definitions/HAL'
- type: array
items:
$ref: '#/definitions/HAL'

View File

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

View File

@@ -10,14 +10,7 @@ The following must be available in the CI environment before testing:
```text ```text
$ node -v $ node -v
v7.5.0 v12.16.0
```
2. **Ruby** runtime MUST be available in the CI environment:
```text
$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]
``` ```
3. [**Dredd**](https://github.com/apiaryio/dredd) MUST be installed globally in the CI environment: 3. [**Dredd**](https://github.com/apiaryio/dredd) MUST be installed globally in the CI environment:
@@ -28,55 +21,22 @@ The following must be available in the CI environment before testing:
```text ```text
$ dredd --version $ dredd --version
dredd v2.2.5 (Darwin 16.4.0; x64) dredd v13.0.1
``` ```
4. [**Apiary CLI Tool**](https://help.apiary.io/tools/apiary-cli) MUST be installed globally in the CI environment:
```text
$ gem install apiaryio
```
```text
$ apiary version
0.8.0
```
5. **Apiary API Key** MUST be set in the CI Environment environment variables:
```text
$ export APIARY_API_KEY=xyz
```
To obtain an Apiary API key, head to [https://login.apiary.io/tokens](https://login.apiary.io/tokens) \(NOTE: You will need the "ALL" Scope\)
## Testing an API ## Testing an API
### Test Run Prerequisites ### Test Run Prerequisites
To test an API within the CI environment provisioned as mentioned in the environment prerequisites, you will need the following: 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 1. A `swagger.yaml` file with the description of API being tested
```text The OpenAPI Specifciation file should be fetched from [API Design Platform](design-plaform.md). In the case of SwaggerHub API Design Platform, the file can be fetched manually or via their API. Refer to [Integrating with the SwaggerHub API](https://swagger.io/blog/api-development/integrating-with-the-swaggerhub-api/), for details how to use SwaggerHub API.
$ export APIARY_API_NAME=bomapi3
```
> See [How to find the Apiary API name](https://help.apiary.io/faq/find-api-name/) for more details. Alternativelly this can also be a remote file e.g. SwaggerHub URL, if the API is public its OAS file and reachable from the testing host.
2. A `swagger.yaml` file with the description of API being tested 2. The host \(address\) of the service being tested
To fetch the swagger.yaml file from Apiary run the following command before the test:
```text
$ apiary fetch --api-name=$APIARY_API_NAME --output="swagger.yaml"
```
The swagger document for Apiary project `bomapi3` was saved as local file `./swagger.yaml`.
> See [Fetching Published Documentation](https://help.apiary.io/tools/apiary-cli/#fetching-published-documentation).
3. The host \(address\) of the service being tested
```text ```text
$ export API_HOST=http://deheremap7336.emea.adsint.biz:8004` $ export API_HOST=http://deheremap7336.emea.adsint.biz:8004`
@@ -84,10 +44,10 @@ To test an API within the CI environment provisioned as mentioned in the environ
### Running the Test ### 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: Run:
```text ```text
$ dredd swagger.yaml $API_HOST -r apiary $ dredd swagger.yaml $API_HOST
``` ```
> See [Dredd Command-line Interface](https://dredd.readthedocs.io/en/latest/usage-cli/). > See [Dredd Command-line Interface](https://dredd.readthedocs.io/en/latest/usage-cli/).
@@ -98,5 +58,4 @@ The Dredd will perform the tests and exits usually if the tests have passed. You
$ echo $? $ echo $?
``` ```
Everything else but `0` should break the build. The test results will be visible in the CLI \(log\) as well as in Apiary. Everything else but `0` should break the build. The test results will be visible in the CLI \(log\)

View File

@@ -1,5 +1,7 @@
# Complete API Development # Complete API Development
> NOTE: The content of this file is outdated, refering to previous technologies used at adidas. It is kept for reference until its refresh
1. **Design the API** 1. **Design the API**
1. Analyze business requirements 1. Analyze business requirements
2. Identify affordances 2. Identify affordances

View File

@@ -4,7 +4,7 @@ The [`application/problem+json`](https://tools.ietf.org/html/rfc7807) \(Problem
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. Problem Detail is intended for use with the HTTP status codes 4xx and 5xx. Problem Detail **MUST NOT** be used with 2xx status code responses.
At the minimum, any Problem Detail response **MUST** have the `title` and `detail` fields. At the minimum, any Problem Detail response **MUST** have the `title` and `detail` fields. `title` value **SHOULD NOT** change from occurrence to occurence of the problem, except for purposes of localization (e.g., using proactive content negotiation) [read more](https://tools.ietf.org/html/rfc7807#section-3.1)
### Example ### Example
@@ -15,6 +15,8 @@ At the minimum, any Problem Detail response **MUST** have the `title` and `detai
} }
``` ```
> NOTE: `title` and `detail` fields **SHOULD NOT** be parsed to determine the nature of the error. Instead `type` **MUST** be used.
## Optional Fields ## 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. 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.
@@ -39,7 +41,7 @@ If needed, the Problem Detail **MAY** include additional fields, refer to [RFC78
When necessary, a Problem Detail response **MAY** include additional error details about the problems that have occurred. When necessary, a Problem Detail response **MAY** include additional error details about the problems that have occurred.
These additional errors **MUST** be under the `errors` and **MUST** follow the Problem Detail structure. These additional errors **MUST** be under the `errors` collection and **MUST** follow the Problem Detail structure.
### Example ### Example
@@ -122,5 +124,8 @@ A Problem Detail response **MUST NOT** contain a program stack trace or server l
## Working with Problem Detail ## 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\). An API description **MAY** list all the error codes with which the API responds. The error responses **SHOULD** describre the error object model schema. It is **RECOMMENDED** to include examples of a possible error response. The error description and/or error example **MAY** list all the types of errors returned for a given error code.
## External resources
There are a whole plethora of libraries working with Problem Detail, for example, see [Zalando / Problem](https://github.com/zalando/problem) \(Java\).

View File

@@ -8,6 +8,12 @@ The [`application/hal+json`](http://stateless.co/hal_specification.html) \(HAL\)
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). 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).
## HAL Document Object Model
HAL document follow the object model defined in JSON-schema [here](https://supermodel.io/adidas/api/HAL).
YAML code snippets are provided for [OpenAPI Specification 2.0/Swagger](https://github.com/adidas/api-guidelines/tree/4a033eb0cf8ec582102c09c1eb5ba1fa8a5597d9/rest-api-guidelines/functionality/message/HAL-snippet.yaml) and [OpenAPI Specification 3.x](https://github.com/adidas/api-guidelines/tree/4a033eb0cf8ec582102c09c1eb5ba1fa8a5597d9/rest-api-guidelines/functionality/message/HAL-snippet-full-OpenApi3.yaml).
## Simple Document Example ## Simple Document Example
The simplest Hal document looks like an empty JSON \(it is an empty JSON!\): The simplest Hal document looks like an empty JSON \(it is an empty JSON!\):
@@ -113,6 +119,8 @@ Some APIs using HAL:
Refer to the [extensive list of libraries that work with HAL](https://github.com/mikekelly/hal_specification/wiki/Libraries). Refer to the [extensive list of libraries that work with HAL](https://github.com/mikekelly/hal_specification/wiki/Libraries).
For working with HAL and Node.js using [HALson npm package](https://www.npmjs.com/package/halson) is suggested.
### Spring Framework ### Spring Framework
Spring framework supports HAL out of the box. More info can be found in [Spring Documentation](https://spring.io/guides/gs/rest-hateoas/) and [examples](https://github.com/spring-guides/gs-rest-hateoas). Spring framework supports HAL out of the box. More info can be found in [Spring Documentation](https://spring.io/guides/gs/rest-hateoas/) and [examples](https://github.com/spring-guides/gs-rest-hateoas).

View File

@@ -2,4 +2,9 @@
* [Product tokens](https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-16#section-6.3) * [Product tokens](https://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-16#section-6.3)
* [Deprecating "X-"](https://tools.ietf.org/html/rfc6648) * [Deprecating "X-"](https://tools.ietf.org/html/rfc6648)
* [Collection of standards and specifications for HTTP/REST APIs](http://standards.rest)
* [Official list of HTTP Message Headers](https://www.iana.org/assignments/message-headers/message-headers.xhtml)
## Tools documentation
* [SwaggerHub Documentation](https://app.swaggerhub.com/help/index)

View File

@@ -10,7 +10,7 @@ Once you are familiar with the **HTTP message structure** learn about the **HTTP
Each HTTP request method, status code, and header have its semantics defined, and every API **MUST** strictly adhere to it. Each HTTP request method, status code, and header have its semantics defined, and every API **MUST** strictly adhere to it.
Follow the [Robustness Principle](../../../general-guidelines/robustness.md). Use only the HTTP request methods, response codes and HTTP headers you understand, be liberal in accepting others. Follow the [Robustness Principle](../../general-guidelines/robustness.md). Use only the HTTP request methods, response codes and HTTP headers you understand, be liberal in accepting others.
## Know HTTP ## Know HTTP

View File

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

View File

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

View File

@@ -2,7 +2,7 @@
## adidas REST API Guidelines ## adidas REST API Guidelines
The adidas REST API Guidelines defines standards and guidelines for building REST APIs at adidas. **These Guidelines has to be followed in addition to the adidas** [**General API Guidelines.**](../general-guidelines/general-guidelines.md) Adidas REST API Guidelines define standards and guidelines for building REST APIs at adidas. **These Guidelines have to be followed in addition to the Adidas** [**General API Guidelines.**](../general-guidelines/general-guidelines.md)
The REST API Guidelines are further split into the following parts: The REST API Guidelines are further split into the following parts:
@@ -11,26 +11,26 @@ The REST API Guidelines are further split into the following parts:
REST API Guidelines Core Principles defines the rules that **MUST** be followed at throughout the full API lifecycle. REST API Guidelines Core Principles defines the rules that **MUST** be followed at throughout the full API lifecycle.
* **Functionality Guidelines** * **Functionality Guidelines**
* \*\*\*\*[**Protocol level**](functionality/protocol/)\*\*\*\* * \*\*\*\*[**Protocol level**](protocol/)\*\*\*\*
Protocol guidelines define the protocols used within the organization. Protocol guidelines define the protocols used within the organization.
* \*\*\*\*[**Message level**](functionality/message/)\*\*\*\* * \*\*\*\*[**Message level**](message/)\*\*\*\*
The Message guidelines define the structure and semantics of messages used to exchange information. The Message guidelines define the structure and semantics of messages used to exchange information.
* \*\*\*\*[**Application level**](functionality/application/) * \*\*\*\*[**Application level**](application/)
The Application guidelines define the definition and use of application-specific semantics. The Application guidelines define the definition and use of application-specific semantics.
* **Quality Guidelines** * **Quality Guidelines**
Evolution and Execution guidelines define the rules for achieving the desired architectural qualities of systems. Evolution and Execution guidelines define the rules for achieving the desired architectural qualities of systems.
* \*\*\*\*[**Evolution**](quality/evolution/)\*\*\*\* * \*\*\*\*[**Evolution**](evolution/)\*\*\*\*
Evolution qualities governance, such as testability, maintainability, extensibility, and scalability. Evolution qualities governance, such as testability, maintainability, extensibility, and scalability.
* \*\*\*\*[**Execution**](quality/execution/)\*\*\*\* * \*\*\*\*[**Execution**](execution/)\*\*\*\*
Execution qualities governance, such as security and usability. Execution qualities governance, such as security and usability.

View File

@@ -1,20 +1,3 @@
# Examples # Examples
Sample APIs following the guidelines are available at [adidas-group GitHub](https://github.com/adidas-group). The samples include the following: Sample APIs following the guidelines are available at in the [examples repository folder](https://github.com/adidas/api-guidelines/tree/master/examples).
### [Simple API](https://github.com/adidas-group/demo-simple-api)
Very simple API including implementation, testing, and full CI/CD lifecycle.
### [Approval API](https://github.com/adidas-group/demo-approval-api)
Real-world API with state transition, API key client app authentication, exposed via API management.
### [Orders API](https://github.com/adidas-group/demo-orders-api)
Sample API used as the template for newly created projects at Apiary.
### [Appointment Service](https://github.com/adidas-group/demo-appointment-service)
Demo API, including implementation and testing used during training.
### [Complex Search Parameters](https://github.com/adidas-group/demo-complex-search)
Sample API showcasing description of complex query parameter rules.

View File

@@ -22,4 +22,3 @@ Adidas-API-Key: 9kfapap6612jkfd3ja9323q
Host: adidas.api.mashery.com Host: adidas.api.mashery.com
``` ```
> NOTE: See more details in the [[Demo] Approval API](http://docs.demoapprovalapi.apiary.io) example.

23
ruleset.md Normal file
View File

@@ -0,0 +1,23 @@
# Adidas API Guidelines Ruleset
- all JSON fields MUST follow `camelCase`
- field names MUST be ASCII alphanumeric characters or `_` or `$`
- collection/array fields MUST have names in plural
- all requests go through `https` protocol
- every API operation MUST have at least one `2xx` response
- `GET` request MUST NOT accept a `body` parameter
- all success responses MUST be of media type `application/hal+json`
- all error responses MUST be of media type `application/problem+json`
- every request SHOULD support `application/json` media type
- `application/hal+json` follows https://supermodel.io/adidas/api/HAL `JSON-Schema`
- `application/problem+json` messages MUST include `title` and `detail` fields
- `application/problem+json` messages SHOULD include `type` field
- date and time MUST follow `ISO 8601` standard: https://www.iso.org/iso-8601-date-and-time-format.html
- language codes MUST follow `ISO 639` standard: https://www.iso.org/iso-639-language-codes.html
- country codes MUST follow `ISO 3166 alpha-2` standard: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
- currency codes MUST follow `ISO 4217` standard: https://en.wikipedia.org/wiki/ISO_4217
- `202` response code is used after creating an asynchronous process request
- a successful and finished async api request returns `303` response code and sends the target resource location in the `Link` header
- `URI` template ([RFC 6570](https://tools.ietf.org/html/rfc6570)) cannot contain a `-` character
- `HTTP` headers MUST use `Hyphenated-Pascal-Case` notation
- `HTTP` headers SHOULD NOT include [`X-` headers](2). All non-standard headers are named without the `X-` prefix.

3
supermodel/.super Normal file
View File

@@ -0,0 +1,3 @@
{
"host": "https://supermodel.io"
}

View File

@@ -0,0 +1,63 @@
$id: http://supermodel.io/adidas/api/HAL
$schema: http://json-schema.org/draft-07/schema#
title: HAL
description: JSON Hypertext Application Language. Definition of [HAL message format](https://tools.ietf.org/html/draft-kelly-json-hal-08)
type: object
properties:
_links:
type: object
additionalProperties:
anyOf:
- $ref: '#/definitions/halLinkObject'
- type: array
items:
- $ref: '#/definitions/halLinkObject'
properties:
curies:
anyOf:
- $ref: '#/definitions/halCuriesLink'
- type: array
items:
- $ref: '#/definitions/halCuriesLink'
_embedded:
type: object
additionalProperties:
anyOf:
- $ref: '#'
- type: array
items:
- $ref: '#'
definitions:
halLinkObject:
title: HAL Link Object
type: object
properties:
href:
type: string
templated:
type: boolean
type:
type: string
deprecation:
type: string
name:
type: string
profile:
type: string
title:
type: string
hreflang:
type: string
required:
- href
halCuriesLink:
title: HAL Curies Link
allOf:
- type: object
properties:
templated:
enum:
- true
required:
- templated
- $ref: '#/definitions/halLinkObject'

View File

@@ -0,0 +1,19 @@
$id: http://supermodel.io/adidas/api/ProblemDetail
$schema: http://json-schema.org/draft-07/schema#
title: Problem Details for HTTP APIs
description: Definition of [RFC7807](https://tools.ietf.org/html/rfc7807) problem detail
type: object
properties:
type:
type: string
title:
type: string
status:
type: number
detail:
type: string
instance:
type: string
required:
- title
- detail

View File

@@ -0,0 +1,22 @@
$id: http://supermodel.io/adidas/examples/order/Order
$schema: http://json-schema.org/draft-07/schema#
title: Order
type: object
description: Order model description
properties:
orderNumber:
type: number
itemCount:
type: number
status:
type: string
required:
- orderNumber
- itemCount
examples:
- orderNumber: 42
itemCount: 3
status: pending

View File

@@ -0,0 +1,23 @@
$id: http://supermodel.io/adidas/examples/order/api/Order
$schema: http://json-schema.org/draft-07/schema#
title: Order HAL Representation
type: object
allOf:
- $ref: http://supermodel.io/adidas/api/HAL
- $ref: http://supermodel.io/adidas/examples/order/Order
examples:
- _links:
self:
href: /orders/1234
edit:
href: /orders/1234
delete:
href: /orders/1234
profile:
href: https://adidas-group.com/gdm/OMS
orderNumber: 1234
itemCount: 42
status: pending

View File

@@ -0,0 +1,14 @@
$id: http://supermodel.io/adidas/examples/order/api/OrderPatch
$schema: http://json-schema.org/draft-07/schema#
title: OrderPatch
description: OrderPatch model description
type: object
allOf:
- $ref: 'http://supermodel.io/adidas/examples/order/Order'
examples:
- status: cancelled
orderNumber: 1
itemCount: 2

View File

@@ -0,0 +1,36 @@
$id: http://supermodel.io/adidas/examples/order/api/Orders
$schema: http://json-schema.org/draft-07/schema#
title: Collection of Orders HAL Representation
type: object
allOf:
- $ref: http://supermodel.io/adidas/api/HAL
examples:
- _links:
self:
href: /orders
create:
href: /orders
next:
href: /orders?offset=5&limit=5
first:
href: /orders?offset=0&limit=5
last:
href: /orders?offset=40&limit=5
_embedded:
order:
- _links:
self:
href: /orders/1234
edit:
href: /orders/1234
delete:
href: /orders/1234
profile:
href: https://adidas-group.com/gdm/OMS
orderNumber: 1234
itemCount: 42
status: pending

View File

@@ -0,0 +1,9 @@
$id: http://supermodel.io/adidas/examples/order/api/ProblemDetail
$schema: http://json-schema.org/draft-07/schema#
title: Problem Detail
type: object
allOf:
- $ref: http://supermodel.io/adidas/api/ProblemDetail

1625
yarn.lock Normal file

File diff suppressed because it is too large Load Diff