Skip to content

Commit a72a7b9

Browse files
authored
feat: Improvements to api guidelines (#92)
- Add documentationUrl to custom spectral rules - Add information about known Entur HTTP headers - Add more information about x-entur-metadata content
1 parent 2d6f58b commit a72a7b9

4 files changed

Lines changed: 135 additions & 24 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
2727
annotations=$(mktemp)
2828
markdown=$(mktemp)
29-
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=$?
29+
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=$?
3030
3131
#Return code 2 means that spectral command failed to run (not linting errors), so fail workflow.
3232
if [ "$rc" -eq 2 ]; then
@@ -59,7 +59,7 @@ jobs:
5959
6060
annotations=$(mktemp)
6161
markdown=$(mktemp)
62-
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=$?
62+
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=$?
6363
6464
#Return code 2 means that spectral command failed to run (not linting errors), so fail workflow.
6565
if [ "$rc" -eq 2 ]; then

.spectral.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ rules:
2323

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

3233
entur-info-title-no-api:
3334
message: "API titles SHOULD NOT contain the word 'api'."
35+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
3436
severity: warn
3537
given: $.info.title
3638
then:
@@ -43,6 +45,7 @@ rules:
4345
# HTTP Methods
4446
entur-operation-standard-methods:
4547
message: "Operations SHOULD use standard HTTP methods (`get`, `post`, `put`, `patch`, `delete`). Invalid operation: {{property}}."
48+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
4649
given: $.paths[*]
4750
severity: warn
4851
then:
@@ -54,6 +57,7 @@ rules:
5457
# Documentation with examples
5558
entur-example-parameter:
5659
message: "Parameters SHOULD have example values."
60+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
5761
severity: warn
5862
recommended: false
5963
given: $.paths.*.*.parameters.*
@@ -63,6 +67,7 @@ rules:
6367

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

7277
entur-example-schema-property:
7378
message: "Properties in components schema SHOULD have example values."
79+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
7480
severity: warn
7581
recommended: false
7682
#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)
@@ -81,13 +87,15 @@ rules:
8187

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

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

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

105114
entur-operation-summary:
106115
message: "Operations SHOULD have a non-empty summary field."
116+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
107117
severity: warn
108118
given: $.paths.*[get,post,put,patch,delete,options,head,trace]
109119
then:
@@ -113,6 +123,7 @@ rules:
113123
# openapi spec version 3
114124
entur-openapi-version-3:
115125
message: "OpenAPI specification must use version 3.x"
126+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
116127
severity: error
117128
given: "$"
118129
then:
@@ -126,6 +137,7 @@ rules:
126137
# Security - HTTPS requirement
127138
entur-hosts-https-only:
128139
message: "Servers MUST use HTTPS. Invalid URL: {{value}}"
140+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#21-general-design-principles"
129141
severity: error
130142
given: $.servers[*].url
131143
then:
@@ -135,6 +147,7 @@ rules:
135147

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

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

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

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

235+
entur-info-metadata-audience:
236+
message: "The OpenAPI info section SHOULD include \"x-entur-metadata.audience\"."
237+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#24-entur-metadata"
238+
severity: warn
239+
given: $
240+
then:
241+
field: info.x-entur-metadata.audience
242+
function: truthy
243+
244+
entur-info-metadata-audience-valid:
245+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#24-entur-metadata"
246+
severity: error
247+
given: $.info.x-entur-metadata.audience
248+
then:
249+
function: enumeration
250+
functionOptions:
251+
values:
252+
- open
253+
- partner
254+
- internal
255+
256+
entur-info-metadata-owner:
257+
message: "The OpenAPI info section SHOULD include \"x-entur-metadata.owner\"."
258+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#242-specification-owner"
259+
severity: warn
260+
given: $
261+
then:
262+
field: info.x-entur-metadata.owner
263+
function: truthy
264+
265+
entur-info-metadata-owner-valid:
266+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#242-specification-owner"
267+
severity: error
268+
given: $.info.x-entur-metadata.owner
269+
then:
270+
function: pattern
271+
functionOptions:
272+
match: ^team-[a-z0-9]+(-[a-z0-9]+)*$
273+
219274
entur-info-metadata-parent-id-kebab-case:
220275
message: "The \"x-entur-metadata.parentId\" MUST be in lower-kebab-case format. Invalid value: {{value}}"
276+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#243-merging-specifications"
221277
severity: error
222278
given: $.info.x-entur-metadata.parentId
223279
then:
@@ -237,6 +293,7 @@ rules:
237293
# URL format requirements
238294
entur-paths-format:
239295
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}}."
296+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
240297
severity: error
241298
given: $.paths.*~
242299
then:
@@ -250,6 +307,7 @@ rules:
250307
# Field naming conventions
251308
entur-query-parameters-lower-camel-case:
252309
message: "Query parameter names MUST be lowerCamelCase. Invalid name: {{value}}"
310+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
253311
severity: error
254312
given: $.paths.*.*.parameters[?(@.in=='query')].name
255313
then:
@@ -259,6 +317,7 @@ rules:
259317

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

269328
entur-body-fields-lower-camel-case:
270329
message: "Request and Response body field names MUST be lowerCamelCase."
330+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
271331
severity: error
272332
given: $..[?(@property === 'properties')]
273333
then:
@@ -279,6 +339,7 @@ rules:
279339
# Server URL case requirements
280340
entur-server-urls-lowercase:
281341
message: "Server URLs MUST be in lowercase. Invalid URL: {{value}}"
342+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
282343
severity: error
283344
given: $.servers[*].url
284345
then:
@@ -289,6 +350,7 @@ rules:
289350
# Avoid 'api' in paths
290351
entur-paths-with-api:
291352
message: "Paths SHOULD NOT contain 'api'."
353+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#31-resource-naming"
292354
severity: warn
293355
given: $.paths.*~
294356
then:
@@ -302,6 +364,7 @@ rules:
302364

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

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

359425
entur-post-responses-validation:
360426
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"
427+
documentationUrl: "https://github.com/entur/api-guidelines/blob/main/guidelines.md#41-http-status-codes"
361428
severity: error
362429
given: $.paths.*.post.responses.*~
363430
then:
@@ -367,6 +434,7 @@ rules:
367434

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

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

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

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

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

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

0 commit comments

Comments
 (0)