Files
api-guidelines/.spectral.yml
2019-11-25 11:27:05 +01:00

304 lines
10 KiB
YAML

extends: [spectral:oas2, spectral:oas3]
rules:
# ---------------------------------------------------------------------------
# General OAS rules
# ---------------------------------------------------------------------------
operation-operationId: false
operation-tags: info
operation-2xx-response: error
paths-camelCase:
description: All YAML/JSON paths MUST follow camelCase
severity: warn
recommended: true
message: "{{property}} is not camelCase: {{error}}"
given: $.paths[*]~
then:
function: pattern
functionOptions:
# match: "/^(\/{1}(([{]?[a-z])[A-Za-z0-9]*[}]?)*)+$/" # - more generic one, allows /asasd{asdas}sadas pattern but also not closed braces
match: "^\/([a-z][a-zA-Z0-9]+)?(\/[a-z][a-zA-Z0-9]+|\/{[a-z][a-zA-Z0-9]+})*$" # doesn't allow /asasd{asdas}sadas pattern or not closed braces
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$_]*/"
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$_]*/"
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$/"
uri-template-cannot-dash:
description: "The 'URI' template (RFC 6570 - https://tools.ietf.org/html/rfc6570) cannot contain a '-' character"
severity: error
recommended: true
message: "{{property}}: {{description}}"
given: "$.paths[*]~"
then:
function: pattern
functionOptions:
notMatch: "/-/"
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)-/"
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
# ---------------------------------------------------------------------------
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
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
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 ))]"
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"
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
# ---------------------------------------------------------------------------
request-support-json-oas3:
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: pattern
functionOptions:
match: falsy
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: "$"
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: "$"
protocol-https-only-oas3: # 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:/"
response-success-hal-oas3:
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
response-success-hal-body-oas3: # 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