Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:

annotations=$(mktemp)
markdown=$(mktemp)
spectral lint ./specs/reference-spec.json --ruleset ".spectral.yml" -F hint -f github-actions -o.github-actions "$annotations" -f markdown -o.markdown="$markdown" && rc=$? || rc=$?
spectral lint ./specs/reference-spec.json --ruleset ".spectral.yml" --show-documentation-url -F hint -f github-actions -o.github-actions "$annotations" -f markdown -o.markdown="$markdown" && rc=$? || rc=$?

#Return code 2 means that spectral command failed to run (not linting errors), so fail workflow.
if [ "$rc" -eq 2 ]; then
Expand Down Expand Up @@ -59,7 +59,7 @@ jobs:

annotations=$(mktemp)
markdown=$(mktemp)
spectral lint ./specs/reference-spec-with-errors.json --ruleset ".spectral.yml" -F hint -f github-actions -o.github-actions "$annotations" -f markdown -o.markdown="$markdown" && rc=$? || rc=$?
spectral lint ./specs/reference-spec-with-errors.json --ruleset ".spectral.yml" --show-documentation-url -F hint -f github-actions -o.github-actions "$annotations" -f markdown -o.markdown="$markdown" && rc=$? || rc=$?

#Return code 2 means that spectral command failed to run (not linting errors), so fail workflow.
if [ "$rc" -eq 2 ]; then
Expand Down
76 changes: 76 additions & 0 deletions .spectral.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ rules:

entur-info-title:
message: "The OpenAPI info section MUST include a non-empty \"title\"."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: error
given: $
then:
Expand All @@ -31,6 +32,7 @@ rules:

entur-info-title-no-api:
message: "API titles SHOULD NOT contain the word 'api'."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: warn
given: $.info.title
then:
Expand All @@ -43,6 +45,7 @@ rules:
# HTTP Methods
entur-operation-standard-methods:
message: "Operations SHOULD use standard HTTP methods (`get`, `post`, `put`, `patch`, `delete`). Invalid operation: {{property}}."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
given: $.paths[*]
severity: warn
then:
Expand All @@ -54,6 +57,7 @@ rules:
# Documentation with examples
entur-example-parameter:
message: "Parameters SHOULD have example values."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: warn
recommended: false
given: $.paths.*.*.parameters.*
Expand All @@ -63,6 +67,7 @@ rules:

entur-parameter-description:
message: "Parameters SHOULD have a description."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: warn
given: $.paths.*.*.parameters.*
then:
Expand All @@ -71,6 +76,7 @@ rules:

entur-example-schema-property:
message: "Properties in components schema SHOULD have example values."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: warn
recommended: false
#For schema properties where type is not array, or items is not a ref. (Array with ref to other schema does not need an example)
Expand All @@ -81,13 +87,15 @@ rules:

entur-request-body-examples:
message: "Request bodies SHOULD include at least one example."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: warn
given: $.paths.*.*.requestBody.content.*
then:
function: requireExampleOrRef

entur-request-body-description:
message: "Request bodies SHOULD have a description."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: warn
given: $.paths.*.*.requestBody
then:
Expand All @@ -96,6 +104,7 @@ rules:

entur-response-body-examples:
message: "Response bodies SHOULD include at least one example."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: warn
given: $.paths.*.*.responses.*.content.*
then:
Expand All @@ -104,6 +113,7 @@ rules:

entur-operation-summary:
message: "Operations SHOULD have a non-empty summary field."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: warn
given: $.paths.*[get,post,put,patch,delete,options,head,trace]
then:
Expand All @@ -113,6 +123,7 @@ rules:
# openapi spec version 3
entur-openapi-version-3:
message: "OpenAPI specification must use version 3.x"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: error
given: "$"
then:
Expand All @@ -126,6 +137,7 @@ rules:
# Security - HTTPS requirement
entur-hosts-https-only:
message: "Servers MUST use HTTPS. Invalid URL: {{value}}"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: error
given: $.servers[*].url
then:
Expand All @@ -135,6 +147,7 @@ rules:

entur-hosts-not-localhost:
message: "Server URLs SHOULD NOT use localhost or 127.0.0.1 as hostname. Invalid URL: {{value}}"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
severity: warn
given: $.servers[*].url
then:
Expand All @@ -149,6 +162,7 @@ rules:

entur-permissions:
message: "x-entur-permissions must match the schema"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#233-documenting-permissions-for-partner-endpoints"
severity: error
given: $.paths.*[get,post,put,patch,delete,options,head,trace].x-entur-permissions
then:
Expand Down Expand Up @@ -201,6 +215,7 @@ rules:

entur-info-metadata-id:
message: "The OpenAPI info section SHOULD include \"x-entur-metadata.id\"."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#241-identifying-a-specification"
severity: warn
given: $
then:
Expand All @@ -209,15 +224,56 @@ rules:

entur-info-metadata-id-kebab-case:
message: "The \"x-entur-metadata.id\" MUST be in lower-kebab-case format. Invalid value: {{value}}"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#241-identifying-a-specification"
severity: error
given: $.info.x-entur-metadata.id
then:
function: pattern
functionOptions:
match: ^[a-z0-9]+(-[a-z0-9]+)*$

entur-info-metadata-audience:
message: "The OpenAPI info section SHOULD include \"x-entur-metadata.audience\"."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#24-entur-metadata"
severity: warn
given: $
then:
field: info.x-entur-metadata.audience
function: truthy

entur-info-metadata-audience-valid:
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#24-entur-metadata"
severity: error
given: $.info.x-entur-metadata.audience
then:
function: enumeration
functionOptions:
values:
- open
- partner
- internal

entur-info-metadata-owner:
message: "The OpenAPI info section SHOULD include \"x-entur-metadata.owner\"."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#242-specification-owner"
severity: warn
given: $
then:
field: info.x-entur-metadata.owner
function: truthy

entur-info-metadata-owner-valid:
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#242-specification-owner"
severity: error
given: $.info.x-entur-metadata.owner
then:
function: pattern
functionOptions:
match: ^team-[a-z0-9]+(-[a-z0-9]+)*$

entur-info-metadata-parent-id-kebab-case:
message: "The \"x-entur-metadata.parentId\" MUST be in lower-kebab-case format. Invalid value: {{value}}"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#243-merging-specifications"
severity: error
given: $.info.x-entur-metadata.parentId
then:
Expand All @@ -237,6 +293,7 @@ rules:
# URL format requirements
entur-paths-format:
message: "Paths MUST be in kebab-case (lower case and separated with hyphens), with single slashes, and no trailing slash at end of path. Invalid path: {{property}}."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
severity: error
given: $.paths.*~
then:
Expand All @@ -250,6 +307,7 @@ rules:
# Field naming conventions
entur-query-parameters-lower-camel-case:
message: "Query parameter names MUST be lowerCamelCase. Invalid name: {{value}}"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
severity: error
given: $.paths.*.*.parameters[?(@.in=='query')].name
then:
Expand All @@ -259,6 +317,7 @@ rules:

entur-path-parameters-camelCase-alphanumeric:
message: "Path parameter names MUST be lowerCamelCase. Invalid name: {{value}}"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
severity: error
given: $..parameters[?(@.in == 'path')].name
then:
Expand All @@ -268,6 +327,7 @@ rules:

entur-body-fields-lower-camel-case:
message: "Request and Response body field names MUST be lowerCamelCase."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
severity: error
given: $..[?(@property === 'properties')]
then:
Expand All @@ -279,6 +339,7 @@ rules:
# Server URL case requirements
entur-server-urls-lowercase:
message: "Server URLs MUST be in lowercase. Invalid URL: {{value}}"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
severity: error
given: $.servers[*].url
then:
Expand All @@ -289,6 +350,7 @@ rules:
# Avoid 'api' in paths
entur-paths-with-api:
message: "Paths SHOULD NOT contain 'api'."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
severity: warn
given: $.paths.*~
then:
Expand All @@ -302,6 +364,7 @@ rules:

entur-info-version:
message: "The OpenAPI info.version MUST be a valid semantic version (MAJOR.MINOR.PATCH format, e.g. 1.0.0)."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#32-versioning"
severity: error
given: $
then:
Expand All @@ -327,6 +390,7 @@ rules:
# Request body allowed methods
entur-request-body-allowed-methods:
message: "Request body is allowed only for PUT, POST, and PATCH."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#41-http-status-codes"
severity: error
given:
- "$.paths[*].get.requestBody"
Expand All @@ -340,6 +404,7 @@ rules:
# HTTP method responses validation
entur-get-responses-validation:
message: "Invalid response code: {{property}}. GET responses MUST use one of these response codes: 200, 304, 400, 401, 403, 404, 500, 503"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#41-http-status-codes"
severity: error
given: $.paths.*.get.responses.*~
then:
Expand All @@ -349,6 +414,7 @@ rules:

entur-delete-responses-validation:
message: "Invalid response code: {{property}}. DELETE responses MUST use one of these response codes: 200, 204, 400, 401, 403, 404, 409, 500, 503"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#41-http-status-codes"
severity: error
given: $.paths.*.delete.responses.*~
then:
Expand All @@ -358,6 +424,7 @@ rules:

entur-post-responses-validation:
message: "Invalid response code: {{property}}. POST responses MUST use one of these response codes: 200, 201, 202, 204, 303, 400, 401, 403, 404, 409, 500, 503"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#41-http-status-codes"
severity: error
given: $.paths.*.post.responses.*~
then:
Expand All @@ -367,6 +434,7 @@ rules:

entur-put-responses-validation:
message: "Invalid response code: {{property}}. PUT responses MUST use one of these response codes: 200, 204, 400, 401, 403, 404, 409, 500, 503"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#41-http-status-codes"
severity: error
given: $.paths.*.put.responses.*~
then:
Expand All @@ -376,6 +444,7 @@ rules:

entur-patch-responses-validation:
message: "Invalid response code: {{property}}. PATCH responses MUST use one of these response codes: 200, 204, 400, 401, 403, 404, 409, 500, 503"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#41-http-status-codes"
severity: error
given: $.paths.*.patch.responses.*~
then:
Expand All @@ -391,6 +460,7 @@ rules:
# Error response format validation
entur-rfc-9457-content-type:
message: "Error responses MUST have content type application/problem+json or application/problem+xml"
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#42-error-handling"
severity: warn
given: $.paths.*.*.responses[?(@property.match(/^(4|5)/))]
then:
Expand All @@ -408,6 +478,7 @@ rules:

entur-rfc-9457-body-title:
message: "Error responses MUST have property 'title'."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#42-error-handling"
severity: error
given: $.paths.*.*.responses[?(@property.match(/^(4|5)/))].content.*.schema.properties
then:
Expand All @@ -416,6 +487,7 @@ rules:

entur-rfc-9457-body-status:
message: "Error responses MUST have property 'status'."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#42-error-handling"
severity: error
given: $.paths.*.*.responses[?(@property.match(/^(4|5)/))].content.*.schema.properties
then:
Expand All @@ -424,6 +496,7 @@ rules:

entur-rfc-9457-body-detail:
message: "Error responses SHOULD have property 'detail' to provide additional context."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#42-error-handling"
severity: warn
given: $.paths.*.*.responses[?(@property.match(/^(4|5)/))].content.*.schema.properties
then:
Expand All @@ -442,6 +515,7 @@ rules:

entur-language-headers:
message: "Accept-Language and Content-Language should follow IETF BCP 47. And macrolanguages like 'no' should not be used - use 'nb' or 'nn'."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#41-language--spelling"
severity: error
given:
- $..parameters[?(@.in=='header' && @.name=='Accept-Language')].example
Expand Down Expand Up @@ -477,6 +551,7 @@ rules:
# ET-Client-Name header not necessary
entur-not-et-client-name-header:
message: "Declaring header \"ET-Client-Name\" is not necessary."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#55-http-headers"
severity: warn
given: "$.paths[*]..parameters[?(@.in == 'header' && @.name == 'ET-Client-Name')].name"
then:
Expand All @@ -485,6 +560,7 @@ rules:
# Header naming conventions
entur-headers-hyphenated-pascal-case:
message: "HTTP header names MUST be in Hyphenated-Pascal-Case. Invalid name: \"{{value}}\"."
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#55-http-headers"
severity: error
given: "$..parameters[?(@.in == 'header' && @.name != 'ET-Client-Name')].name"
then:
Expand Down
Loading