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
15 changes: 14 additions & 1 deletion linter/spectral.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ rules:

#/core/path-segments-kebab-case
nlgov:paths-kebab-case:
severity: warn
severity: error
message: "{{property}} is not kebab-case."
given: $.paths[?(@property && !@property.match(/\/openapi\.json/))]~
then:
Expand All @@ -146,6 +146,19 @@ rules:
# - Een pad mag eindigen met een `/`. Dat is volgens een andere regel niet toegestaan, maar we willen niet twee errors genereren
match: ^(\/|(\/_[a-z0-9]+|\/(([a-z0-9\-]+|{[^}]+})(\/([a-z0-9\-\.]+|{[^}]+}))*)(\/_[a-z]+)?)\/?)$

#/core/query-keys-camel-case
nlgov:query-keys-camel-case:
severity: error
message: "{{value}} is not lower camelCase."
given:
- $.paths.*.*.parameters[?(@.in=='query')]
- $.components.securitySchemes[?(@.in=='query')]
then:
function: pattern
field: name
functionOptions:
match: ^\$?[a-z][a-z\d]*([A-Z][a-z\d]*)*$

nlgov:schema-camel-case:
severity: warn
message: "Schema name should be UpperCamelCase in {{path}}"
Expand Down
4 changes: 2 additions & 2 deletions linter/testcases/cor-api/expected-output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/testcases/cor-api/openapi.json
70:35 warning nlgov:use-problem-schema The content type of an error response should be application/problem+json or application/problem+xml to match RFC 9457. paths./heartbeat.get.responses[429].content
80:35 warning nlgov:use-problem-schema The content type of an error response should be application/problem+json or application/problem+xml to match RFC 9457. paths./heartbeat.get.responses[503].content
181:29 warning nlgov:paths-kebab-case /laatsteWijziging is not kebab-case. paths./laatsteWijziging
181:29 error nlgov:paths-kebab-case /laatsteWijziging is not kebab-case. paths./laatsteWijziging
211:35 warning nlgov:use-problem-schema The content type of an error response should be application/problem+json or application/problem+xml to match RFC 9457. paths./laatsteWijziging.get.responses[400].content
221:35 warning nlgov:use-problem-schema The content type of an error response should be application/problem+json or application/problem+xml to match RFC 9457. paths./laatsteWijziging.get.responses[404].content
231:35 warning nlgov:use-problem-schema The content type of an error response should be application/problem+json or application/problem+xml to match RFC 9457. paths./laatsteWijziging.get.responses[405].content
Expand All @@ -25,4 +25,4 @@
734:35 warning nlgov:use-problem-schema The content type of an error response should be application/problem+json or application/problem+xml to match RFC 9457. paths./organisaties/{oin}.get.responses[500].content
744:35 warning nlgov:use-problem-schema The content type of an error response should be application/problem+json or application/problem+xml to match RFC 9457. paths./organisaties/{oin}.get.responses[503].content

✖ 24 problems (0 errors, 24 warnings, 0 infos, 0 hints)
✖ 24 problems (1 error, 23 warnings, 0 infos, 0 hints)
4 changes: 2 additions & 2 deletions linter/testcases/paths-kebab-incorrect/expected-output.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

/testcases/paths-kebab-incorrect/openapi.json
67:25 warning nlgov:paths-kebab-case /camelCasePad is not kebab-case. paths./camelCasePad
67:25 error nlgov:paths-kebab-case /camelCasePad is not kebab-case. paths./camelCasePad

✖ 1 problem (0 errors, 1 warning, 0 infos, 0 hints)
✖ 1 problem (1 error, 0 warnings, 0 infos, 0 hints)
9 changes: 9 additions & 0 deletions linter/testcases/query-keys-camel-case/expected-output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

/testcases/query-keys-camel-case/openapi.json
84:33 error nlgov:query-keys-camel-case kebab-case is not lower camelCase. paths./resource.get.parameters[1].name
91:33 error nlgov:query-keys-camel-case _startMetUnderscore is not lower camelCase. paths./resource.get.parameters[2].name
98:33 error nlgov:query-keys-camel-case 9startMetGetal is not lower camelCase. paths./resource.get.parameters[3].name
105:33 error nlgov:query-keys-camel-case snake_case is not lower camelCase. paths./resource.get.parameters[4].name
112:33 error nlgov:query-keys-camel-case UpperCamelCase is not lower camelCase. paths./resource.get.parameters[5].name

✖ 5 problems (5 errors, 0 warnings, 0 infos, 0 hints)
155 changes: 155 additions & 0 deletions linter/testcases/query-keys-camel-case/openapi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
{
"openapi": "3.0.3",
"info": {
"title": "Baseline",
"description": "Deze OpenAPI specification bevat het minimale om aan alle regels te voldoen.",
"contact": {
"name": "Beheerder",
"url": "https://www.example.com",
"email": "mail@example.com"
},
"version": "1.0.0"
},
"servers": [
{
"url": "https://example.com/api/v1"
}
],
"security": [
{
"default": []
}
],
"tags": [
{
"name": "openapi"
},
{
"name": "resource"
}
],
"paths": {
"/openapi.json": {
"get": {
"tags": [
"openapi"
],
"description": "OpenAPI document",
"operationId": "getOpenapiJSON",
"parameters": [],
"responses": {
"200": {
"description": "OK",
"headers": {
"API-Version": {
"description": "De huidige versie van de applicatie",
"style": "simple",
"schema": {
"type": "string"
}
},
"access-control-allow-origin": {
"description": "Alle origins mogen bij deze resource",
"schema": {
"type": "string"
}
}
}
}
},
"security": [
{
"default": []
}
]
}
},
"/resource": {
"get": {
"tags": [
"resource"
],
"description": "resource",
"operationId": "getResource",
"parameters": [
{
"in": "query",
"name": "lowerCamelCase",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "kebab-case",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "_startMetUnderscore",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "9startMetGetal",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "snake_case",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "UpperCamelCase",
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "OK",
"headers": {
"API-Version": {
"description": "De huidige versie van de applicatie",
"style": "simple",
"schema": {
"type": "string"
}
}
}
}
},
"security": [
{
"default": []
}
]
}
}
},
"components": {
"schemas": {
},
"securitySchemes": {
"default": {
"type": "oauth2",
"flows": {
"implicit": {
"authorizationUrl": "https://test.com",
"scopes": {}
}
}
}
}
}
}
9 changes: 5 additions & 4 deletions sections/designRules.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ https://api.example.org/v1/vergunningen/d285e05c-6b01-45c3-92d8-5e19a946b66f</pr
<dt>Statement</dt>
<dd>
<div>
<p>Query keys in a [=URI=] MUST only contain letters and digits, where the first letter of each word is capitalized, except for the first letter of the entire compound word. This is also known as <a href="https://developer.mozilla.org/en-US/docs/Glossary/Camel_case">lower camelCase</a>. This also implies that diacritics MUST be normalized and special characters MUST be omitted.
<p>Query keys in a [=URI=] MUST only contain letters and digits, where the first letter of each word is capitalized, except for the first letter (MUST NOT be a digit) of the entire compound word. This is also known as <a href="https://developer.mozilla.org/en-US/docs/Glossary/Camel_case">lower camelCase</a>. This also implies that diacritics MUST be normalized and special characters MUST be omitted.
</div>
</dd>
<dt>Rationale</dt>
Expand All @@ -178,14 +178,15 @@ https://api.example.org/v1/vergunningen/d285e05c-6b01-45c3-92d8-5e19a946b66f</pr
<pre class="nohighlight example-correct">https://api.example.org/v1/gebouwen?typeGebouw=woning</pre>
<p>URI query key not using camelCase (incorrect):</p>
<pre class="nohighlight example-incorrect">https://api.example.org/v1/gebouwen?type-gebouw=woning</pre>
<p>URI query key starts with digit (incorrect):</p>
<pre class="nohighlight example-incorrect">https://api.example.org/v1/gebouwen?2ndReviewer=alice</pre>
</aside>
</dd>
<dt>How to test</dt>
<dd>
Loop all resource paths in the OpenAPI Description and check that all query keys use letters, digits in camelCase.
Loop all resource paths in the OpenAPI Description and check that all query keys use letters, digits in camelCase. You can use the following regex for each query key:
<aside class="example">
You can use the following regex for each query key:
<pre><code>^[a-z0-9]+[a-zA-Z0-9]*$</code></pre>
<pre><code>^\$?[a-z][a-z\d]*([A-Z][a-z\d]*)*$</code></pre>
</aside>
</dd>
</dl>
Expand Down
Loading