Skip to content

Commit 01888f0

Browse files
committed
added linting rules for root path and api info schema, plus other
smaller updates.
1 parent 60ab54a commit 01888f0

17 files changed

+546
-156
lines changed

.github/workflows/lint-example-oas.yml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,21 @@ jobs:
2020
name: Lint Example OpenAPI
2121

2222
runs-on: ubuntu-latest
23+
24+
permissions:
25+
contents: read
26+
issues: read
27+
checks: write
28+
pull-requests: write
29+
2330
steps:
2431
- name: Checkout code
2532
uses: actions/checkout@v4
2633

27-
# Run Spectral
28-
- uses: stoplightio/spectral-action@latest
29-
with:
30-
file_glob: "./example/*.{json,yml,yaml}"
34+
- name: Install spectral
35+
run: curl -L https://raw.github.com/stoplightio/spectral/master/scripts/install.sh | sh
36+
37+
- name: Lint example OpenAPI
38+
run: |
39+
spectral --version
40+
spectral lint "./example/*.{json,yml,yaml}" -f github-actions

docs/api-design-guidelines/pagination-filtering-sorting.md

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,7 @@ paths:
7676
description: The type of test to filter by.
7777
schema:
7878
type: string
79-
examples:
80-
- Lateral Flow Test
79+
example: Lateral Flow Test
8180
- in: query
8281
name: result
8382
required: false
@@ -88,10 +87,7 @@ paths:
8887
- POSITIVE
8988
- NEGATIVE
9089
- UNREADABLE
91-
examples:
92-
- POSITIVE
93-
- NEGATIVE
94-
- UNREADABLE
90+
example: POSITIVE
9591
```
9692
9793
### Alternative Example
@@ -119,18 +115,14 @@ paths:
119115
type: string
120116
pattern: '^\d{3}(?:-| )?\d{3}(?:-| )?\d{4}$'
121117
description: The nhs number of patient
122-
examples:
123-
- '4857773456'
124-
- '485 777 3456'
125-
- '485-777-3456'
118+
example: '4857773456'
126119
- in: query
127120
name: type
128121
required: false
129122
description: The type of test to filter by.
130123
schema:
131124
type: string
132-
examples:
133-
- Lateral Flow Test
125+
example: Lateral Flow Test
134126
- in: query
135127
name: result
136128
required: false
@@ -141,10 +133,7 @@ paths:
141133
- POSITIVE
142134
- NEGATIVE
143135
- UNREADABLE
144-
examples:
145-
- POSITIVE
146-
- NEGATIVE
147-
- UNREADABLE
136+
example: POSITIVE
148137
```
149138
150139
## Sorting
@@ -158,3 +147,22 @@ If a explicit sort order is desired, the query parameter `sort` **SHOULD** be us
158147
``` text
159148
GET /product/v1/results?sort=nhsNumber|asc,type|desc
160149
```
150+
151+
``` yaml
152+
components:
153+
parameters:
154+
sortParam:
155+
in: query
156+
name: sort
157+
description: How to sort the results.
158+
schema:
159+
type: string
160+
pattern: ^[a-z]+(?:[A-Z][a-z]+)+\|(?:asc|desc)(?:,[a-z]+(?:[A-Z][a-z]+)*\|(?:asc|desc))*$
161+
examples:
162+
sortBySingleField:
163+
value: nhsNumber|asc
164+
summary: Sort by a single field
165+
sortByMultipleField:
166+
value: nhsNumber|asc,type|desc
167+
summary: Sort by multiple fields
168+
```

docs/api-design-guidelines/versioning-and-deprecation.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,15 @@ Avoid:
6464
6565
`MINOR` and `PATCH` versions **MUST NOT** be added to the URI as they do not affect compatibility.
6666
67-
There **SHOULD** be an endpoint to return version metadata that is also documented in the OpenAPI definition.
67+
## API root endpoint
68+
69+
There **SHOULD** be an endpoint to return version metadata (typically the APIs root `/` endpoint) that is also documented in the OpenAPI definition, not only will this provide useful API metadata but will help API consumers know they're looking at the right place instead of getting a `404` or random `500` error as is common in some APIs.
6870
6971
``` text
7072
GET /namespace/product/v1
71-
73+
7274
{
73-
"name": "product",
75+
"name": "Product API",
7476
"version": "1.0.1"
7577
"releaseDate": "2024-09-17"
7678
"documentation": "https://developer.ukhsa.gov.uk/namespace/product/v1/docs"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# **MUST** return 200 for api root
2+
3+
Root path **MUST** define a `200` response.
4+
5+
## Valid Example
6+
7+
``` yaml
8+
paths:
9+
/:
10+
get:
11+
summary: Get API information.
12+
description: Get API information.
13+
operationId: getApiInfo
14+
tags:
15+
- API Meta Information
16+
responses:
17+
'200':
18+
description: This response returns a information about the API.
19+
content:
20+
application/json:
21+
schema:
22+
$ref: '#/components/schemas/ApiInfo'
23+
default:
24+
$ref: '#/components/responses/UnexpectedError'
25+
```
26+
27+
[UKHSA Guidlelines Versioning](../../api-design-guidelines/versioning-and-deprecation.md#api-root-endpoint)

docs/spectral-rules/must/must-use-normalized-paths-without-empty-path-segments.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ Path segments **MUST** not contain duplicate slashes.
55
## Invalid Example
66

77
``` yaml
8-
/user//report:
8+
paths:
9+
/user//report:
910
```
1011
1112
## Valid Example
1213
1314
``` yaml
14-
/beach-report:
15+
paths:
16+
/user-report:
1517
```
1618
1719
[Zalando Guideline 136](https://opensource.zalando.com/restful-api-guidelines/#136)

docs/spectral-rules/must/must-use-normalized-paths-without-trailing-slash.md

Lines changed: 0 additions & 17 deletions
This file was deleted.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# **MUST** use normalised paths
2+
3+
Path **MUST** start with a slash and **MUST NOT** end with a slash (except root path `/`).
4+
5+
## Invalid Example
6+
7+
``` yaml
8+
paths:
9+
/patient/:
10+
...
11+
/patient/{patientId}/results/:
12+
```
13+
14+
## Valid Example
15+
16+
``` yaml
17+
paths:
18+
/:
19+
...
20+
/patient:
21+
...
22+
/patient/{patientId}/results:
23+
```
24+
25+
[Zalando Guideline 136](https://opensource.zalando.com/restful-api-guidelines/#136)

docs/spectral-rules/must/must-use-valid-problem-json-schema.md

Lines changed: 33 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,42 @@
22

33
`Problem` schema **MUST** include this set of minimal required properties and validations:
44

5-
``` yaml
6-
type: object
7-
properties:
8-
type:
9-
type: string
10-
format: uri-reference
11-
title:
12-
type: string
13-
status:
14-
type: integer
15-
format: int32
16-
detail:
17-
type: string
18-
instance:
19-
type: string
20-
```
21-
225
## Valid Example
236

247
``` yaml
25-
title: Problem
26-
type: object
27-
properties:
28-
type:
29-
type: string
30-
format: uri-reference
31-
example: /my-example/user-error
32-
title:
33-
type: string
34-
example: a title for the error situation
35-
status:
36-
type: integer
37-
format: int32
38-
detail:
39-
type: string
40-
example: description for the error situation
41-
instance:
42-
type: string
43-
format: uri-reference
44-
example: /some/uri-reference#specific-occurrence-context
8+
ProblemDetails:
9+
type: object
10+
description: Schema for detailed problem information.
11+
properties:
12+
type:
13+
type: string
14+
description: A URI reference that identifies the problem type.
15+
format: uri-reference
16+
maxLength: 1024
17+
status:
18+
type: integer
19+
description: The HTTP status code generated by the origin server for this occurrence of the problem.
20+
format: int32
21+
minimum: 100
22+
maximum: 599
23+
title:
24+
type: string
25+
description: A short, human-readable summary of the problem type. It should not change from occurrence to occurrence of the problem, except for purposes of localization.
26+
maxLength: 1024
27+
detail:
28+
type: string
29+
description: A human-readable explanation specific to this occurrence of the problem.
30+
maxLength: 4096
31+
instance:
32+
type: string
33+
description: A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced.
34+
maxLength: 1024
35+
required:
36+
- type
37+
- status
38+
- title
39+
- detail
40+
- instance
4541
```
4642
4743
[Zalando Guideline 176](https://opensource.zalando.com/restful-api-guidelines/#176)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# **MUST** use valid version info schema
2+
3+
`ApiInfo` schema **MUST** include this set of minimal required properties and validations:
4+
5+
## Valid Example
6+
7+
``` yaml
8+
components:
9+
schema:
10+
...
11+
ApiInfo:
12+
type: object
13+
description: Schema for detailing API information.
14+
properties:
15+
name:
16+
type: string
17+
description: The name of the API.
18+
example: Test Results API
19+
version:
20+
type: string
21+
pattern: '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$'
22+
description: The version of the API.
23+
example: 1.0.0
24+
releaseDate:
25+
type: string
26+
format: date
27+
description: The release date of this API version.
28+
example: 2025-02-26
29+
documentation:
30+
type: string
31+
format: uri
32+
description: A URL to the API documentation.
33+
example: https://developer.ukhsa.gov.uk/namespace/product/v1/docs
34+
releaseNotes:
35+
type: string
36+
format: uri
37+
description: A URL to the API release notes.
38+
example: https://developer.ukhsa.gov.uk/namespace/product/v1/releaseNotes
39+
required:
40+
- name
41+
- version
42+
- releaseDate
43+
- documentation
44+
- releaseNotes
45+
```

docs/spectral-rules/should/should-always-return-json-objects-as-top-level-data-structures.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ requestBody:
2929
type: string
3030
```
3131
32-
[UKHSA API Design](../../api-design-guidelines/api-design.md#response-format)
32+
[UKHSA Guidlines API Design](../../api-design-guidelines/api-design.md#response-format)
3333
3434
[Zalando Guideline 210](https://opensource.zalando.com/restful-api-guidelines/#210)

0 commit comments

Comments
 (0)