api-quality-spectral-ruleset 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1119 @@
1
+ functionsDir: './functions'
2
+ functions:
3
+ - apq-alternate-paths
4
+ - apq-custom-schema
5
+ - apq-compare-insensitive
6
+ - apq-parameter-naming-convention
7
+ - apq-resources-by-verb
8
+ - apq-at-most-one-body-parameter
9
+ - apq-standard-response-codes
10
+ extends:
11
+ - spectral:asyncapi
12
+ - spectral:oas
13
+ rules:
14
+ apiq:OAR001:
15
+ description: "For security reasons and as a REST best practice, the HTTPS protocol is mandatory."
16
+ message: "OAR001: HTTPS protocol is mandatory."
17
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR001.md"
18
+ severity: "error"
19
+ given: "$.servers[*].url"
20
+ then:
21
+ function: pattern
22
+ functionOptions:
23
+ match: "^https://"
24
+ apiq:OAR002:
25
+ description: "A wrong scope definition may cause problems to import the API definition into WSO2."
26
+ message: "OAR002: Scope definition must include the 'key' attribute along with 'name' and 'roles'."
27
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR002.md"
28
+ severity: "error"
29
+ given: "$.x-wso2-security.apim.x-wso2-scopes[*]"
30
+ then:
31
+ - function: "truthy"
32
+ field: "key"
33
+ message: "Scope must define a 'key' attribute."
34
+ apiq:OAR003:
35
+ description: "A description can help other developers to understand the correct use of the scope."
36
+ message: "OAR003: Scope must define a 'description' attribute."
37
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR003.md"
38
+ severity: "error"
39
+ given: "$.x-wso2-security.apim.x-wso2-scopes[*]"
40
+ then:
41
+ - function: "truthy"
42
+ field: "description"
43
+ message: "Scope must define a 'description' attribute."
44
+ apiq:OAR004:
45
+ description: "A role with forbidden characters may cause problems in some applications."
46
+ message: "OAR004: Role should not contain forbidden characters (e.g. special characters like €, *, etc.)."
47
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR004.md"
48
+ severity: "error"
49
+ given: "$.x-wso2-security.apim.x-wso2-scopes[*].roles"
50
+ then:
51
+ function: "pattern"
52
+ functionOptions:
53
+ match: "^[A-Za-z0-9_]+$"
54
+ apiq:OAR005:
55
+ description: "A wrong scope may cause problems to import the API definition into WSO2 or allow all users to call the endpoint."
56
+ message: "OAR005: Scope in the operation must be defined correctly and match an existing scope."
57
+ severity: "error"
58
+ given: "$.paths[*][*].x-scope"
59
+ then:
60
+ - function: "truthy"
61
+ message: "Scope must be defined in the operation."
62
+ - function: enumeration
63
+ functionOptions:
64
+ values:
65
+ - read
66
+ - write
67
+ apiq:OAR006:
68
+ description: "Routes must define request media types supported by the API."
69
+ message: "OAR006: Specify at least one Media Type in the content of the request body."
70
+ severity: "error"
71
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR006.md"
72
+ given: "$.paths[*][post,put,patch]"
73
+ then:
74
+ - field: "requestBody"
75
+ function: truthy
76
+ - field: "requestBody.content"
77
+ function: truthy
78
+ apiq:OAR007:
79
+ description: "Routes must define response media types supported by the API"
80
+ message: "OAR007: Specify at least one Media Type in the content of the response body."
81
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR007.md"
82
+ severity: "error"
83
+ given: "$.paths[*][get,post,put,patch,delete].responses[?(@property != '204')]"
84
+ then:
85
+ - field: "content"
86
+ function: truthy
87
+ apiq:OAR008:
88
+ description: "HTTP verbs not encouraged."
89
+ message: "OAR008: Only the REST standard verbs are allowed (POST, GET, PUT, PATCH and DELETE)."
90
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR008.md"
91
+ severity: error
92
+ given: "$.paths[*][?(@property == 'get' || @property == 'post' || @property == 'put' || @property == 'delete' || @property == 'patch')]"
93
+ then:
94
+ function: truthy
95
+ apiq:OAR009:
96
+ description: "Default request media type should be defined for operations."
97
+ message: "OAR009: Default request media type is mandatory."
98
+ severity: "error"
99
+ given: "$..content"
100
+ then:
101
+ field: "application/json"
102
+ function: truthy
103
+ apiq:OAR010:
104
+ description: "Default response media type should be defined for responses."
105
+ message: "OAR010: Default response media type is mandatory."
106
+ severity: warn
107
+ given: "$.paths[*][get,post,put,patch,delete].responses[*]"
108
+ then:
109
+ field: "content['application/json']"
110
+ function: truthy
111
+ apiq:OAR011:
112
+ description: "URLs should follow the specified naming convention: all literal path segments must be in kebab-case."
113
+ message: "OAR011: The resource names with more than two words must be compliant with the standard naming convention (kebab-case)."
114
+ severity: error
115
+ given: "$.paths[*]~"
116
+ then:
117
+ function: pattern
118
+ functionOptions:
119
+ match: "^(\/|[a-z0-9-]+|{[a-zA-Z0-9_|-]+})+$"
120
+ apiq:OAR012:
121
+ description: "Path params, query params, object names and property names should follow the configured naming convention. You can configure snake_case (default), kebab-case, camelCase or UpperCamelCase"
122
+ message: "OAR012: Path params, query params, object names and property names must follow the configured naming convention."
123
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR012.md"
124
+ severity: warn
125
+ given:
126
+ - "$.paths[*][*].parameters[?(@.in == 'path' || @.in == 'query')].name"
127
+ - "$.paths[*][*].parameters[*].schema.properties.*~"
128
+ - "$.paths[*][*].requestBody..schema.properties.*~"
129
+ - "$.paths[*][*].responses..schema.properties.*~"
130
+ - "$.components.schemas.*~"
131
+ then:
132
+ function: apq-parameter-naming-convention
133
+ functionOptions:
134
+ namingConvention: "snake_case"
135
+ apiq:OAR013:
136
+ description: "Default response is required for all operations."
137
+ message: "OAR013: Default response is required."
138
+ severity: error
139
+ given: "$.paths[*][get,post,put,patch,delete].responses"
140
+ then:
141
+ field: "default"
142
+ function: truthy
143
+ apiq:OAR014:
144
+ description: "Resources depth level should be below the non-suggested range."
145
+ message: "OAR014: The number of parts of the path must be less than 4."
146
+ severity: warn
147
+ given: "$.paths.*~"
148
+ then:
149
+ function: pattern
150
+ functionOptions:
151
+ notMatch: "^(?:\\/[^\\/]+){4,}"
152
+ apiq:OAR015:
153
+ description: "Resources depth level should be smaller than 5."
154
+ message: "OAR015: Path exceeds the maximum allowed depth level of 5."
155
+ severity: error
156
+ given: "$.paths.*~"
157
+ then:
158
+ function: pattern
159
+ functionOptions:
160
+ match: "^\/[^\/]*((\/{[^}]*})*\/[^\/]*(\/{[^}]*})*){0,4}\/?$"
161
+ apiq:OAR016:
162
+ description: "Numeric types requires a valid format."
163
+ message: "OAR016: Numeric types must use a valid format for their type."
164
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR016.md"
165
+ severity: error
166
+ given:
167
+ - "$..[?(@.type == 'integer' && @.format)]"
168
+ - "$..[?(@.type == 'number' && @.format)]"
169
+ then:
170
+ function: schema
171
+ functionOptions:
172
+ schema:
173
+ oneOf:
174
+ - properties:
175
+ type:
176
+ const: integer
177
+ format:
178
+ enum: [int32, int64]
179
+ - properties:
180
+ type:
181
+ const: number
182
+ format:
183
+ enum: [float, double]
184
+ apiq:OAR017:
185
+ description: "Resource path should alternate static and parametrized parts."
186
+ message: "OAR017: Resource path should alternate static and parametrized parts."
187
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR017.md"
188
+ severity: error
189
+ given: "$.paths.*~"
190
+ then:
191
+ function: apq-alternate-paths
192
+ functionOptions:
193
+ except: ["me"]
194
+ apiq:OAR018:
195
+ description: Operation not recommended for resource path depending on HTTP verb
196
+ message: "OAR018: Operation not recommended for resource path: {{path}} ({{verb}})"
197
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR018.md"
198
+ severity: warn
199
+ given: "$.paths"
200
+ then:
201
+ function: apq-resources-by-verb
202
+ functionOptions:
203
+ allowed-resources-paths: |
204
+ ;get:^/[^/{}]+$
205
+ ;get:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+$
206
+ ;get:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+$
207
+ ;get:^/[^/{}]+/(\{[^/{}]+\}|me)$
208
+ ;get:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)$
209
+ ;get:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)$
210
+
211
+ ;post:^/[^/{}]+$
212
+ ;post:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+$
213
+ ;post:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+$
214
+ ;post:^/[^/{}]+/get$
215
+ ;post:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/get$
216
+ ;post:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/get$
217
+ ;post:^/[^/{}]+/delete$
218
+ ;post:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/delete$
219
+ ;post:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/delete$
220
+
221
+ ;put:^/[^/{}]+/(\{[^/{}]+\}|me)$
222
+ ;put:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)$
223
+ ;put:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)$
224
+
225
+ ;patch:^/[^/{}]+/(\{[^/{}]+\}|me)$
226
+ ;patch:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)$
227
+ ;patch:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)$
228
+
229
+ ;delete:^/[^/{}]+/(\{[^/{}]+\}|me)$
230
+ ;delete:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)$
231
+ ;delete:^/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)/[^/{}]+/(\{[^/{}]+\}|me)$
232
+ apiq:OAR019:
233
+ description: "$select must be defined as a query parameter in all operations."
234
+ message: "OAR019: $select must be defined as a query parameter in this operation."
235
+ severity: warn
236
+ given: "$.paths[*].get.parameters"
237
+ then:
238
+ field: "$[?(@.name == '$select' && @.in == 'query')]"
239
+ function: truthy
240
+ apiq:OAR020:
241
+ description: "$expand must be defined as a query parameter in all operations."
242
+ message: "OAR020: $expand must be defined as a query parameter in this operation."
243
+ severity: warn
244
+ given: "$.paths[*].get.parameters"
245
+ then:
246
+ field: "$[?(@.name == '$expand' && @.in == 'query')]"
247
+ function: truthy
248
+ apiq:OAR021:
249
+ description: "$exclude must be defined as a query parameter in all operations."
250
+ message: "OAR021: $exclude must be defined as a query parameter in this operation."
251
+ severity: warn
252
+ given: "$.paths[*].get.parameters"
253
+ then:
254
+ field: "$[?(@.name == '$exclude' && @.in == 'query')]"
255
+ function: truthy
256
+ apiq:OAR022:
257
+ description: "$orderby must be defined as a query parameter in all operations."
258
+ message: "OAR022: $orderby must be defined as a query parameter in this operation."
259
+ severity: warn
260
+ given: "$.paths[*].get.parameters"
261
+ then:
262
+ field: "$[?(@.name == '$orderby' && @.in == 'query')]"
263
+ function: truthy
264
+ apiq:OAR023:
265
+ description: "$total must be defined as a query parameter in all operations."
266
+ message: "OAR023: $total must be defined as a query parameter in this operation."
267
+ severity: error
268
+ given: "$.paths[*].get.parameters"
269
+ then:
270
+ field: "$[?(@.name == '$total' && @.in == 'query')]"
271
+ function: truthy
272
+ apiq:OAR024:
273
+ description: "$start must be defined as a query parameter in all operations."
274
+ message: "OAR024: $start must be defined as a query parameter in this operation."
275
+ severity: error
276
+ given: "$.paths[*].get.parameters"
277
+ then:
278
+ field: "$[?(@.name == '$start' && @.in == 'query')]"
279
+ function: truthy
280
+ apiq:OAR025:
281
+ description: "$limit must be defined as a query parameter in all operations."
282
+ message: "OAR025: $limit must be defined as a query parameter in this operation."
283
+ severity: error
284
+ given: "$.paths[*].get.parameters"
285
+ then:
286
+ field: "$[?(@.name == '$limit' && @.in == 'query')]"
287
+ function: truthy
288
+ apiq:OAR026:
289
+ description: "The $total parameter default value should be false."
290
+ message: "OAR026: The $total parameter default value should be false."
291
+ severity: error
292
+ given: "$.paths[*].get.parameters[?(@.name == '$total' && @.in == 'query')]"
293
+ then:
294
+ field: "schema.default"
295
+ function: falsy
296
+ apiq:OAR027:
297
+ description: "Location header is required in responses with code 201 from POST operations."
298
+ message: "OAR027: Location header is required in responses with code 201 from POST operations."
299
+ severity: error
300
+ given: "$.paths.*.post.responses['201']"
301
+ then:
302
+ field: "headers.Location.schema.type"
303
+ function: truthy
304
+ apiq:OAR028:
305
+ description: "$filter must be defined as a query parameter in all operations."
306
+ message: "OAR028: $filter must be defined as a query parameter in this operation."
307
+ severity: warn
308
+ given: "$.paths[*].get.parameters"
309
+ then:
310
+ field: "$[?(@.name == '$filter' && @.in == 'query')]"
311
+ function: truthy
312
+ apiq:OAR029:
313
+ description: "A response not compliant with the standard may cause application issues."
314
+ message: "OAR029: A response not compliant with the standard may cause application issues."
315
+ severity: error
316
+ given: "$.components.schemas.errorResponse"
317
+ then:
318
+ function: schema
319
+ functionOptions:
320
+ schema:
321
+ type: object
322
+ properties:
323
+ properties:
324
+ type: object
325
+ properties:
326
+ error:
327
+ type: object
328
+ properties:
329
+ properties:
330
+ type: object
331
+ properties:
332
+ code:
333
+ type: string
334
+ message:
335
+ type: string
336
+ details:
337
+ type: array
338
+ httpStatus:
339
+ type: integer
340
+ required:
341
+ - code
342
+ - message
343
+ - httpStatus
344
+ required:
345
+ - properties
346
+ apiq:OAR030:
347
+ description: "The path '/status' must be declared."
348
+ message: "OAR030: The path '/status' must be declared."
349
+ severity: error
350
+ given: "$.paths"
351
+ then:
352
+ field: "/status"
353
+ function: truthy
354
+ apiq:OAR031:
355
+ description: The examples can help developers to understand the response data structure and representation."
356
+ message: "OAR031: Examples - Parameters, Request Body and Responses must have an examples defined."
357
+ severity: error
358
+ given:
359
+ - $.paths.*.*.parameters.*
360
+ - $.paths.*.*[responses,requestBody]..content.*
361
+ then:
362
+ field: examples
363
+ function: truthy
364
+ apiq:OAR032:
365
+ description: "Ambiguous path parts not encouraged."
366
+ message: "OAR032: When reading a URL, it must be possible to interpret which resources it is referring to in a concrete way. Ambiguous names in resources must be avoided."
367
+ severity: error
368
+ given: "$.paths.*~"
369
+ then:
370
+ field: "name"
371
+ function: pattern
372
+ functionOptions:
373
+ notMatch: "^.*elements|instances|resources|values|terms|objects|items|elements|instances|resources|values.*$"
374
+ apiq:OAR033:
375
+ description: "Headers 'Accept', 'Content-Type', and 'Authorization' are not allowed."
376
+ message: "OAR033: The header '{{value}}' is not allowed."
377
+ severity: error
378
+ given: "$.paths[*][get,post,put,patch,delete].parameters[?(@.in == 'header')]"
379
+ then:
380
+ field: "name"
381
+ function: pattern
382
+ functionOptions:
383
+ notMatch: "^(Accept|Content-Type|Authorization)$"
384
+ apiq:OAR034:
385
+ description: "A paged response not compliant with the standard may cause application issues."
386
+ message: "OAR034: Paged response schema must be compliant with the standard."
387
+ severity: error
388
+ given: "$.paths[*][*].responses[?(@property != '204' && @property != '304' && @property != 'default')]"
389
+ then:
390
+ field: content
391
+ function: truthy
392
+ apiq:OAR035:
393
+ description: "Response code 401 must be defined for operations with security schemes defined."
394
+ message: "OAR035: Response code 401 must be defined for operations with security schemes defined."
395
+ severity: "error"
396
+ given: "$.paths[*][*].responses"
397
+ then:
398
+ function: truthy
399
+ field: "401"
400
+ message: "Operation must define a 401 Unauthorized response for security schemes."
401
+ apiq:OAR036:
402
+ description: "Cookie use is forbidden as a session mechanism."
403
+ message: "OAR036: Cookie use is forbidden as a session mechanism."
404
+ severity: error
405
+ given:
406
+ - "$.paths[*][get,post,put,patch,delete].parameters[?(@.in == 'header')]"
407
+ - "$.paths[*][get,post,put,patch,delete].responses[*].headers.*~"
408
+ then:
409
+ field: "name"
410
+ function: pattern
411
+ functionOptions:
412
+ notMatch: "^(Cookie|Set-Cookie)$"
413
+ apiq:OAR037:
414
+ description: "Schema should use well-defined type and format."
415
+ message: "OAR037: String schemas must specify a valid format (date, date-time, password, byte, binary, email, uuid, uri, hostname, ipv4, or ipv6)."
416
+ severity: error
417
+ given: "$..schema..[?(@.type=='string')]"
418
+ then:
419
+ field: format
420
+ function: pattern
421
+ functionOptions:
422
+ match: "^(date|date-time|password|byte|binary|email|uuid|uri|hostname|ipv4|ipv6)$"
423
+ apiq:OAR038:
424
+ description: "Response schema must be compliant with the standard."
425
+ message: "OAR038: Response property is required for status code '{{property}}'."
426
+ severity: error
427
+ given: "$.paths.*.*.responses..content..schema.properties"
428
+ then:
429
+ field: "@key"
430
+ function: pattern
431
+ functionOptions:
432
+ match: "^data|error$"
433
+ apiq:OAR039:
434
+ description: "Response codes must be defined according to the standard depending on the HTTP verb and resource path."
435
+ message: "{{error}}"
436
+ documentationUrl: https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR039.md
437
+ severity: error
438
+ given: "$.paths[*][*]"
439
+ then:
440
+ function: apq-standard-response-codes
441
+ functionOptions:
442
+ resources-exclusions:
443
+ - "get:/status"
444
+ required-codes-by-resources-paths: >
445
+ ;get:^/[^/{}]+$:200|206,400,500,503
446
+ ;get:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+$:200|206,400,500,503,404
447
+ ;get:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+$:200|206,400,500,503,404
448
+ ;get:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,400,404,500,503
449
+ ;get:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,400,404,500,503
450
+ ;get:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,400,404,500,503
451
+ ;post:^/[^/{}]+$:200|201|202,400,415,500,503
452
+ ;post:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+$:200|201|202,400,415,500,503,404
453
+ ;post:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+$:200|201|202,400,415,500,503,404
454
+ ;post:^/[^/{}]+/get$:200,404,400,415,500,503
455
+ ;post:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/get$:200,404,400,415,500,503
456
+ ;post:^/[^/{}]+/delete$:200,404,400,415,500,503
457
+ ;post:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/delete$:200,404,400,415,500,503
458
+ ;put:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,404,400,415,500,503
459
+ ;put:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,404,400,415,500,503
460
+ ;put:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,404,400,415,500,503
461
+ ;delete:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,400,404,500,503
462
+ ;delete:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,400,404,500,503
463
+ ;delete:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,400,404,500,503
464
+ ;patch:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,404,400,415,500,503
465
+ ;patch:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,404,400,415,500,503
466
+ ;patch:^/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)/[^/{}]+/(\{[^/{}]+\}|\bme\b)$:200,404,400,415,500,503
467
+ apiq:OAR040:
468
+ description: "A scope name non-compliant with the standard may cause problems at application level."
469
+ message: "OAR040: Scope name must follow the 'apfc_sc_' prefix standard."
470
+ severity: "error"
471
+ given: "$.x-wso2-security.apim.x-wso2-scopes[*].name"
472
+ then:
473
+ function: pattern
474
+ functionOptions:
475
+ match: "^apfc_sc_.*"
476
+ apiq:OAR041:
477
+ description: Available scopes must be defined at the end of the document, at the root level, inside `x-wso2-security`.
478
+ message: "OAR041:Scopes must be defined in `x-wso2-security` at the end of the document, before the paths."
479
+ severity: "error"
480
+ given: "$.paths['/pets'].get"
481
+ then:
482
+ field: "x-aut-type"
483
+ function: truthy
484
+ apiq:OAR044:
485
+ description: "Declared media type should conform to RFC6838 and RFC7231."
486
+ message: "OAR044: Declared media type range should conform to RFC7231."
487
+ severity: "error"
488
+ given: "$.paths.*.*.responses.*.content.*~"
489
+ then:
490
+ field: name
491
+ function: pattern
492
+ functionOptions:
493
+ match: "^application\/[a-zA-Z0-9-_]+$"
494
+ apiq:OAR045:
495
+ description: "Response schema is required for responses with status codes 201 and others that return content."
496
+ message: "OAR045: Response schema is required for status code '{{property}}'."
497
+ severity: error
498
+ given: "$.paths[*][get,post,put,patch,delete].responses[?(@property !== '204')]"
499
+ then:
500
+ field: "content"
501
+ function: truthy
502
+ apiq:OAR046:
503
+ description: "Each operation SHOULD have a tag."
504
+ message: "OAR046: You should categorize the operations of your contract with tags."
505
+ severity: error
506
+ given:
507
+ - "$.paths[*].get"
508
+ - "$.paths[*].post"
509
+ - "$.paths[*].put"
510
+ - "$.paths[*].patch"
511
+ - "$.paths[*].delete"
512
+ then:
513
+ function: schema
514
+ functionOptions:
515
+ schema:
516
+ type: object
517
+ required: ["tags"]
518
+ properties:
519
+ tags:
520
+ type: array
521
+ minItems: 1
522
+ apiq:OAR047:
523
+ description: "Tags required and each tag must have a short description."
524
+ message: "OAR047: Add tags with a short description to each one."
525
+ severity: error
526
+ given: "$"
527
+ then:
528
+ - field: "tags"
529
+ function: schema
530
+ functionOptions:
531
+ schema:
532
+ type: array
533
+ minLength: 1
534
+ items:
535
+ type: object
536
+ required:
537
+ - name
538
+ - description
539
+ properties:
540
+ name:
541
+ type: string
542
+ minLength: 1
543
+ description:
544
+ type: string
545
+ minLength: 1
546
+ apiq:OAR048:
547
+ description: APIs must define at most one body parameter.
548
+ message: "OAR048: An operation can have at most one body parameter"
549
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR048.md"
550
+ severity: error
551
+ formats:
552
+ - oas2
553
+ given: "$.paths[*][*]"
554
+ then:
555
+ field: parameters
556
+ function: apq-at-most-one-body-parameter
557
+ apiq:OAR049:
558
+ description: "204 No Content MUST NOT return any content."
559
+ message: "OAR049: 204 No Content MUST NOT return any content."
560
+ severity: error
561
+ given: "$.paths[*][get,post,put,patch,delete].responses['204']"
562
+ then:
563
+ field: "content"
564
+ function: falsy
565
+ apiq:OAR050:
566
+ description: "Provide a summary for each operation."
567
+ message: "OAR050: Provide a summary for each operation."
568
+ severity: "error"
569
+ given: "$.paths[*][get,post,put,patch,delete]"
570
+ then:
571
+ field: "summary"
572
+ function: truthy
573
+ apiq:OAR051:
574
+ description: "Provide a different summary and description for each operation."
575
+ message: "OAR051: Provide a different summary and description for each operation."
576
+ severity: "error"
577
+ given: "$.paths[*].*"
578
+ then:
579
+ function: apq-compare-insensitive
580
+ functionOptions:
581
+ property: summary
582
+ equalTo: description
583
+ result: falsy
584
+ apiq:OAR052:
585
+ description: "Numeric schema types must define a format."
586
+ message: "OAR052: Numeric types requires a format"
587
+ documentationUrl: "https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR052.md"
588
+ severity: warn
589
+ given: "$..[?(@.type == 'integer' || @.type == 'number')]"
590
+ then:
591
+ field: format
592
+ function: truthy
593
+ apiq:OAR054:
594
+ description: "Ensure the host matches the specified format"
595
+ message: "OAR054: Hostname must be a subdomain of the organization's domain name."
596
+ severity: error
597
+ given: "$.servers[*]"
598
+ then:
599
+ field: url
600
+ function: pattern
601
+ functionOptions:
602
+ match: ^(http(s)?:\/\/.)[-a-zA-Z0-9@:%._\+~#=]{2,256}\.apiquality.io\b([-a-zA-Z0-9@:%_\+.~#?&\/=]*)$
603
+ apiq:OAR060:
604
+ description: "All query parameters must be defined as optional."
605
+ message: "OAR060: All query parameter must be optional (required: false)."
606
+ severity: error
607
+ given: "$.paths[*][get,post,put,patch,delete].parameters[?(@.in == 'query')]"
608
+ then:
609
+ field: "required"
610
+ function: falsy
611
+ apiq:OAR061:
612
+ description: "Ensure get have mandatory response codes"
613
+ message: "OAR061: Ensure get have the mandatory response codes"
614
+ severity: error
615
+ given: "$.paths[?(!(@property === '/status' || @property === '/another'))].get.responses"
616
+ then:
617
+ function: schema
618
+ functionOptions:
619
+ schema:
620
+ oneOf:
621
+ - required: ['200']
622
+ - required: ['202']
623
+ - required: ['206']
624
+ not:
625
+ required: ['201', '204']
626
+ apiq:OAR062:
627
+ description: "Ensure post have mandatory response codes"
628
+ message: "OAR062: Ensure post have the mandatory response codes"
629
+ severity: error
630
+ given: "$.paths[?(!( @property == '/status' || @property == '/another' ))].post.responses"
631
+ then:
632
+ function: schema
633
+ functionOptions:
634
+ schema:
635
+ oneOf:
636
+ - required: ['200']
637
+ - required: ['201']
638
+ - required: ['202']
639
+ - required: ['204']
640
+ - required: ['206']
641
+ apiq:OAR063:
642
+ description: "Ensure put have mandatory response codes"
643
+ message: "OAR063: Ensure put have the mandatory response codes"
644
+ severity: error
645
+ given: "$.paths[?(!( @property == '/status' || @property == '/another' ))].put.responses"
646
+ then:
647
+ function: schema
648
+ functionOptions:
649
+ schema:
650
+ oneOf:
651
+ - required: ['200']
652
+ - required: ['202']
653
+ - required: ['204']
654
+ - required: ['206']
655
+ apiq:OAR064:
656
+ description: "Ensure patch have mandatory response codes"
657
+ message: "OAR064: Ensure patch have the mandatory response codes"
658
+ severity: error
659
+ given: "$.paths[?(!( @property == '/status' || @property == '/another' ))].patch.responses"
660
+ then:
661
+ function: schema
662
+ functionOptions:
663
+ schema:
664
+ oneOf:
665
+ - required: ['200']
666
+ - required: ['202']
667
+ - required: ['204']
668
+ - required: ['206']
669
+ apiq:OAR065:
670
+ description: "Ensure delete have mandatory response codes"
671
+ message: "OAR065: Ensure delete have the mandatory response codes"
672
+ severity: error
673
+ given: "$.paths[?(!( @property == '/status' || @property == '/another' ))].delete.responses"
674
+ then:
675
+ function: schema
676
+ functionOptions:
677
+ schema:
678
+ oneOf:
679
+ - required: ['200']
680
+ - required: ['202']
681
+ - required: ['204']
682
+ apiq:OAR066:
683
+ description: "RequestBody and Responses schema property names must be compliant with the snake_case naming convention."
684
+ message: "OAR066: RequestBody and Responses schema property names must be compliant with the snake_case naming convention."
685
+ severity: "warn"
686
+ given: "$.paths.*.*[responses,requestBody]..content..schema..properties.*~"
687
+ then:
688
+ function: casing
689
+ functionOptions:
690
+ type: snake
691
+ apiq:OAR067:
692
+ description: "RequestBody and Responses schema property names must be compliant with the camelCase naming convention."
693
+ message: "OAR067: RequestBody and Responses schema property names must be compliant with the camelCase naming convention."
694
+ severity: "warn"
695
+ given: "$.paths.*.*[responses,requestBody]..content..schema..properties.*~"
696
+ then:
697
+ function: casing
698
+ functionOptions:
699
+ type: camel
700
+ apiq:OAR068:
701
+ description: "RequestBody and Responses schema property names must be compliant with the PascalCase naming convention."
702
+ message: "OAR068: RequestBody and Responses schema property names must be compliant with the PascalCase naming convention."
703
+ severity: "warn"
704
+ given: "$.paths.*.*[responses,requestBody]..content..schema..properties.*~"
705
+ then:
706
+ function: casing
707
+ functionOptions:
708
+ type: pascal
709
+ apiq:OAR069:
710
+ description: "Any param in PATH or QUERY should have a Bad Request (400) response."
711
+ message: "OAR069: Any param in PATH or QUERY should have a Bad Request (400) response."
712
+ severity: "warn"
713
+ given: "$.paths[*][*].responses"
714
+ then:
715
+ function: truthy
716
+ field: "400"
717
+ message: "Operation must define a 400 Bad Request response for parameters in PATH or QUERY."
718
+ apiq:OAR070:
719
+ description: "Parameters in path should not be numeric."
720
+ message: "OAR070: Parameters in path should not be numeric."
721
+ severity: error
722
+ given: "$.paths[*][get,post,put,patch,delete].parameters[?(@.in == 'path')]"
723
+ then:
724
+ field: "schema.type"
725
+ function: pattern
726
+ functionOptions:
727
+ match: "^(?!integer|number)"
728
+ apiq:OAR071:
729
+ description: "Query parameters 'param1', 'param2', and 'param3' must be defined in the operation."
730
+ message: "OAR071: Query parameters 'param1', 'param2', and 'param3' must be defined."
731
+ severity: error
732
+ given: "$.paths[*].get.parameters"
733
+ then:
734
+ - field: "$[?(@.name == 'param1')]"
735
+ function: truthy
736
+ - field: "$[?(@.name == 'param2')]"
737
+ function: truthy
738
+ - field: "$[?(@.name == 'param3')]"
739
+ function: truthy
740
+ apiq:OAR072:
741
+ description: "Responses with status codes other than 200 must not include 'stacktrace'."
742
+ message: "The response with status code {{property}} must not include 'stacktrace'."
743
+ severity: error
744
+ given: "$.paths[*][get,post,put,patch,delete].responses[?(@property != '200')]"
745
+ then:
746
+ field: "content.application/json.schema.properties"
747
+ function: pattern
748
+ functionOptions:
749
+ notMatch: "stacktrace"
750
+ apiq:OAR073:
751
+ description: "API should include a 429 response to indicate rate limiting, except for the /status path."
752
+ message: "OAR073: API should include a 429 response to indicate rate limiting."
753
+ severity: error
754
+ given: "$.paths[?(@ !== '/status')][*].responses"
755
+ then:
756
+ field: "429"
757
+ function: truthy
758
+ apiq:OAR074:
759
+ description: "Numeric parameters should have minimum, maximum, or format restriction."
760
+ message: "OAR074: Numeric parameter '{{property}}' should have a minimum, maximum, or format restriction."
761
+ severity: error
762
+ given: "$.paths[*][get,post,put,patch,delete].parameters[?(@.schema.type == 'integer' || @.schema.type == 'number')]"
763
+ then:
764
+ function: schema
765
+ functionOptions:
766
+ schema:
767
+ type: object
768
+ properties:
769
+ schema:
770
+ anyOf:
771
+ - required: ["minimum"]
772
+ - required: ["maximum"]
773
+ - required: ["format"]
774
+ apiq:OAR075:
775
+ description: "String parameters should have minLength, maxLength, pattern (regular expression), or enum restriction."
776
+ message: "OAR075: String parameters should have minLength, maxLength, pattern, or enum restriction."
777
+ severity: error
778
+ given: "$.paths[*][get,post,put,patch,delete].parameters[?(@.schema.type == 'string' && @.in == 'path')]"
779
+ then:
780
+ function: schema
781
+ functionOptions:
782
+ schema:
783
+ type: object
784
+ properties:
785
+ schema:
786
+ anyOf:
787
+ - required: ["minLength"]
788
+ - required: ["maxLength"]
789
+ - required: ["pattern"]
790
+ - required: ["enum"]
791
+ apiq:OAR076:
792
+ description: "Schema should use well-defined type and format."
793
+ message: "OAR076: Invalid combination: type '{{value.type}}' with format '{{value.format}}'"
794
+ severity: "error"
795
+ given: "$..[?(@.type=='number')]"
796
+ then:
797
+ field: format
798
+ function: enumeration
799
+ functionOptions:
800
+ values:
801
+ - float
802
+ - double
803
+ apiq:OAR077:
804
+ description: "All parameters in query must be snake_case."
805
+ message: "OAR077: All parameters in query must be snake_case."
806
+ severity: warn
807
+ given: "$.paths[*][*].parameters[?(@.in == 'query')]"
808
+ then:
809
+ field: "name"
810
+ function: pattern
811
+ functionOptions:
812
+ match: ^\$?_?[a-z]+(_[a-z]+)*$
813
+ apiq:OAR078:
814
+ description: "All API methods must have security defined."
815
+ message: "OAR078: The operation '{{property}}' must have security defined."
816
+ severity: error
817
+ given: "$.paths[*][get,post,put,patch,delete]"
818
+ then:
819
+ field: "security"
820
+ function: truthy
821
+ apiq:OAR079:
822
+ description: "Operations with path parameters should include a 404 Not Found response."
823
+ message: "OAR079: Path parameter present, but missing 404 Not Found response."
824
+ severity: "warn"
825
+ given: "$.paths[*][*]"
826
+ then:
827
+ field: responses.404
828
+ function: truthy
829
+ apiq:OAR080:
830
+ description: "The security scheme must be among those allowed by the organization and must be complete."
831
+ message: "OAR080: The security scheme '{{property}}' must be among those allowed by the organization and must be complete."
832
+ severity: error
833
+ given: "$.paths[*][get,post,put,patch,delete].security[*]"
834
+ then:
835
+ field: "@key"
836
+ function: pattern
837
+ functionOptions:
838
+ match: "^(apiKey|oauth2)$"
839
+ apiq:OAR081:
840
+ description: "Fields of type password should be string with format password."
841
+ message: "OAR081: Fields of type password should be string with format password."
842
+ severity: error
843
+ given: "$..properties[?(@.type == 'string' && @.format == 'number')]"
844
+ then:
845
+ field: "format"
846
+ function: pattern
847
+ functionOptions:
848
+ match: "^password$"
849
+ apiq:OAR082:
850
+ description: "The string properties must define a byte or binary format."
851
+ message: "OAR082: The string properties must define a 'byte' or 'binary' format."
852
+ severity: error
853
+ given: "$..properties.*"
854
+ then:
855
+ field: format
856
+ function: pattern
857
+ functionOptions:
858
+ match: "^(byte|binary)$"
859
+ apiq:OAR083:
860
+ description: "Certain parameters (e.g., email, password) should not pass through the querystring."
861
+ message: "OAR083: The parameter '{{value}}' should not pass through the querystring."
862
+ severity: error
863
+ given: "$.paths[*][get,post,put,patch,delete].parameters[?(@.in == 'query')]"
864
+ then:
865
+ field: "name"
866
+ function: pattern
867
+ functionOptions:
868
+ notMatch: "^(email|password)$"
869
+ apiq:OAR084:
870
+ description: "The format password should not pass through the querystring."
871
+ message: "OAR084: The format password should not be used in querystring parameters."
872
+ severity: error
873
+ given: "$.paths[*][get,post,put,patch,delete].parameters[?(@.in == 'query')]"
874
+ then:
875
+ field: "schema.format"
876
+ function: pattern
877
+ functionOptions:
878
+ notMatch: "^password$"
879
+ apiq:OAR085:
880
+ description: "The OpenAPI version must be one of: 2.0, 3.0.0, 3.0.1, 3.0.2, 3.0.3, 3.1.0."
881
+ message: "OAR085: The OpenAPI version '{{value}}' is not allowed. Allowed versions: 2.0, 3.0.0, 3.0.1, 3.0.2, 3.0.3, 3.1.0."
882
+ severity: warn
883
+ given: "$.openapi"
884
+ then:
885
+ function: pattern
886
+ functionOptions:
887
+ match: "^(2\\.0|3\\.0\\.0|3\\.0\\.1|3\\.0\\.2|3\\.0\\.3|3\\.1\\.0)$"
888
+ apiq:OAR086:
889
+ description: "Descriptions must begin with a capital letter, end with a period, and not be empty."
890
+ message: "OAR086: Descriptions must begin with a capital letter, end with a period, and not be empty."
891
+ severity: "warn"
892
+ given: "$..description"
893
+ then:
894
+ function: pattern
895
+ functionOptions:
896
+ match: "^[A-Z][\\s\\S]*\\.$"
897
+ apiq:OAR087:
898
+ description: "Summaries must begin with a capital letter, end with a period, and not be empty."
899
+ message: "OAR087: Summaries must begin with a capital letter, end with a period, and not be empty."
900
+ severity: "warn"
901
+ given: "$..summary"
902
+ then:
903
+ function: pattern
904
+ functionOptions:
905
+ match: "^[A-Z][\\s\\S]*\\.$"
906
+ apiq:OAR088:
907
+ description: "The $ref of a parameter must end with the suffix Param."
908
+ message: "OAR088: The $ref of a parameter must end with the suffix Param."
909
+ severity: "warn"
910
+ given: "$..parameters[*].$ref"
911
+ then:
912
+ function: pattern
913
+ functionOptions:
914
+ match: "Param$"
915
+ apiq:OAR089:
916
+ description: "The $ref of a request body must end with the suffix Body."
917
+ message: "OAR089: The $ref of a request body must end with the suffix Body."
918
+ severity: "warn"
919
+ given: "$..requestBody.$ref"
920
+ then:
921
+ function: pattern
922
+ functionOptions:
923
+ match: "Body$"
924
+ apiq:OAR090:
925
+ description: "The $ref of a response must end with the suffix Response."
926
+ message: "OAR090: The $ref of a response must end with the suffix Response"
927
+ severity: error
928
+ given: "$.paths['/sample'].get.responses['200'].$ref"
929
+ then:
930
+ function: pattern
931
+ functionOptions:
932
+ match: ".*Response$"
933
+ resolved: false
934
+ apiq:OAR091:
935
+ description: "Parameters must contain only $ref references."
936
+ message: "OAR091: Parameters must contain only $ref references."
937
+ severity: error
938
+ given: "$.paths[*][get,post,put,patch,delete].parameters[*].$ref"
939
+ then:
940
+ function: truthy
941
+ apiq:OAR092:
942
+ description: "RequestBody must contain a $ref."
943
+ message: "OAR092: RequestBody must contain a $ref reference."
944
+ severity: error
945
+ given: "$.paths[*][get,post,put,patch,delete].requestBody[*].$ref"
946
+ then:
947
+ function: truthy
948
+ apiq:OAR093:
949
+ description: "RequestBody must contain only references ($ref)."
950
+ message: "OAR093: RequestBody must contain only references ($ref)."
951
+ severity: error
952
+ given: "$.paths[*][get,post,put,patch,delete].responses[*].$ref"
953
+ then:
954
+ function: truthy
955
+ apiq:OAR094:
956
+ description: "Examples must be used instead of example in the content definition for better tool compatibility."
957
+ message: "OAR094: Examples must be used instead of example in the content definition for better tool compatibility."
958
+ severity: warn
959
+ given: "$..content[*].example"
960
+ then:
961
+ function: falsy
962
+ apiq:OAR096:
963
+ description: "Response code 403 must be defined for operations with security schemes defined."
964
+ message: "OAR096: Response code 403 must be defined for operations with security schemes defined."
965
+ severity: "error"
966
+ given: "$.paths[*][*].responses"
967
+ then:
968
+ function: truthy
969
+ field: "403"
970
+ message: "Operation must define a 403 Unauthorized response for security schemes."
971
+ apiq:OAR097:
972
+ description: "The base path must contain at least two parts."
973
+ message: "OAR097: Path has too few parts."
974
+ severity: "error"
975
+ given: "$.servers[*].url"
976
+ then:
977
+ function: pattern
978
+ functionOptions:
979
+ match: "^https?://[^/]+/[^/]+/[^/]+"
980
+ apiq:OAR098:
981
+ description: "The base path must not contain more than two parts."
982
+ message: "OAR098: Path has too many parts."
983
+ severity: "error"
984
+ given: "$.servers[*].url"
985
+ then:
986
+ function: pattern
987
+ functionOptions:
988
+ notMatch: "^https?://[^/]+/([^/]+/){2,}[^/]+"
989
+ apiq:OAR099:
990
+ description: "API name must start with prefix 'api-'."
991
+ message: "OAR099: API name must start with prefix 'api-'."
992
+ severity: "error"
993
+ given:
994
+ - "$.servers[*].url"
995
+ - "$.paths[*]~"
996
+ - "$.basePath"
997
+ then:
998
+ function: pattern
999
+ functionOptions:
1000
+ match: ".*?/api-[^/]+/v[0-9]+"
1001
+ apiq:OAR100:
1002
+ description: "Last path part must be the API version, indicated with the prefix 'v' and the version number as integer."
1003
+ message: "OAR100: Last path part must be the API version, indicated with the prefix 'v' and the version number as integer."
1004
+ severity: "error"
1005
+ given: "$.servers[*].url"
1006
+ then:
1007
+ function: pattern
1008
+ functionOptions:
1009
+ match: "^https?://[^/]+/.*/v[0-9]+$"
1010
+ apiq:OAR101:
1011
+ description: "The first part of the path should be one of the allowed paths (e.g., '/hello')."
1012
+ message: "OAR101: The first part of the path should be one of the allowed paths."
1013
+ severity: "error"
1014
+ given: "$.servers[*].url"
1015
+ then:
1016
+ function: pattern
1017
+ functionOptions:
1018
+ match: "^https?://[^/]+/hello/.*$"
1019
+ apiq:OAR102:
1020
+ description: "The second part of the path should be one of the allowed values."
1021
+ message: "OAR102: The second part of the path should be one of the allowed values."
1022
+ severity: "error"
1023
+ given: "$.servers[*].url"
1024
+ then:
1025
+ function: pattern
1026
+ functionOptions:
1027
+ match: "^https?://[^/]+/hola/hello$"
1028
+ apiq:OAR103:
1029
+ description: "GET requests are not recommended for resource paths containing 'get' or 'delete', as this may indicate a design flaw."
1030
+ message: "OAR103: GET request should not be used on paths containing 'get' or 'delete'."
1031
+ severity: error
1032
+ given: "$.paths[?(@property.match(/(get|delete)/))].get"
1033
+ then:
1034
+ function: falsy
1035
+ apiq:OAR104:
1036
+ description: "POST requests should not be used on paths ending with 'me' or a templated parameter."
1037
+ message: "OAR104: POST requests should not target paths ending in 'me' or a path parameter like '{id}'."
1038
+ severity: error
1039
+ given: "$.paths[?(/\\/(me|{[^}]+})$/.test(@property))].post"
1040
+ then:
1041
+ function: falsy
1042
+ apiq:OAR105:
1043
+ description: "PUT requests are not recommended for resource paths containing 'get' or 'delete', as this may indicate a design flaw."
1044
+ message: "OAR105: PUT request should not be used on paths containing 'get' or 'delete'."
1045
+ severity: error
1046
+ given: "$.paths[?(@property.match(/(get|delete)/))].put"
1047
+ then:
1048
+ function: falsy
1049
+ apiq:OAR106:
1050
+ description: "PATCH requests are not recommended for resource paths containing 'get' or 'delete', as this may indicate a design flaw."
1051
+ message: "OAR106: PATCH request should not be used on paths containing 'get' or 'delete'."
1052
+ severity: error
1053
+ given: "$.paths[?(@property.match(/(get|delete)/))].patch"
1054
+ then:
1055
+ function: falsy
1056
+ apiq:OAR107:
1057
+ description: "DELETE requests are not recommended for resource paths containing 'get' or 'delete', as this may indicate a design flaw."
1058
+ message: "OAR107: DELETE request should not be used on paths containing 'get' or 'delete'."
1059
+ severity: error
1060
+ given: "$.paths[?(@property.match(/(get|delete)/))].delete"
1061
+ then:
1062
+ function: falsy
1063
+ apiq:OAR108:
1064
+ description: "The schemas should match the provided examples."
1065
+ message: "OAR108: Schema does not match the provided example."
1066
+ severity: "error"
1067
+ given:
1068
+ - "$.paths['/item'].get.responses['200'].content['application/json'].example"
1069
+ - "$.paths['/item'].get.responses['200'].examples['application/json']"
1070
+ then:
1071
+ - function: "schema"
1072
+ functionOptions:
1073
+ schema:
1074
+ type: "object"
1075
+ properties:
1076
+ id:
1077
+ type: "integer"
1078
+ nombre:
1079
+ type: "string"
1080
+ apiq:OAR109:
1081
+ description: "Use default response instead of directly specifying 5XX codes."
1082
+ message: "OAR109: Use default response instead of specifying 5XX codes directly."
1083
+ severity: error
1084
+ given: "$.paths[*][get,post,put,patch,delete].responses"
1085
+ then:
1086
+ field: "$[?(@property.match(/^5[0-9][0-9]$/))]"
1087
+ function: falsy
1088
+ apiq:OAR110:
1089
+ description: "License information cannot be empty."
1090
+ message: "OAR110: License information cannot be empty."
1091
+ severity: "error"
1092
+ given: "$.info"
1093
+ then:
1094
+ field: "license"
1095
+ function: truthy
1096
+ apiq:OAR111:
1097
+ description: "Contact information cannot be empty."
1098
+ message: "OAR111: Contact information cannot be empty."
1099
+ severity: "error"
1100
+ given: "$.info"
1101
+ then:
1102
+ field: "contact"
1103
+ function: truthy
1104
+ apiq:OAR114:
1105
+ description: There are mandatory response headers and others that are not allowed.
1106
+ message: "OAR114: Missing mandatory response x-api-key and x-trace-id headers, or forbidden headers are present."
1107
+ documentationUrl: https://github.com/apiaddicts/apquality-spectral/blob/main/docs/resources/OAR114.md
1108
+ severity: error
1109
+ given: "$.paths[*][*].responses[*].headers"
1110
+ then:
1111
+ - function: schema
1112
+ functionOptions:
1113
+ schema:
1114
+ type: object
1115
+ required:
1116
+ - x-api-key
1117
+ - x-trace-id
1118
+ propertyNames:
1119
+ pattern: "^(x-api-key|x-trace-id|traceId|dateTime)$"