| Description: |
The API Handbook
states that the response to a "list" operation returning a collection must be an object that contains an array property
whose name matches the plural form of the resource type.
For example, the "GET /v1/things" operation should return an object
with an array property named "things" (which is presumably defined as an array of Thing instances).
This rule enforces this requirement by checking each operation that appears to be a
"list"-type operation (with or without support for pagination) to make sure that the operation's
response schema defines an array property whose name matches the last path segment
within the operation's path string, which should also match the plural form of the resource type.
For the purposes of this rule, an operation is considered to be a "list"-type operation
if it is a "get" request and one of the following are also true:
- the operation's operationId starts with "list" (e.g. "list_things")
- the operation's path string does not end with a path parameter reference, but there is a
companion path string that does end with a path parameter reference (e.g. "/v1/things" vs "/v1/things/{thing_id}").
</ol>
</td>
</tr>
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
get:
operationId: list_things
responses:
'200':
content:
'application/json':
schema:
type: object
properties:
abuncha_things:
type: array
items:
$ref: '#/components/schemas/Thing'
|
</tr>
| Compliant example: |
paths:
'/v1/things':
get:
operationId: list_things
responses:
'200':
content:
'application/json':
schema:
type: object
properties:
things:
type: array
items:
$ref: '#/components/schemas/Thing'
|
</table>
### ibm-content-contains-schema
| Rule id: |
ibm-content-contains-schema |
| Description: |
Each request body and response content field should contain a schema.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
responses:
200:
description: 'Success response!'
content:
application/json:
# schema not provided
|
</tr>
| Compliant example: |
responses:
200:
description: 'Success response!'
content:
application/json:
schema:
type: string
|
</table>
### ibm-content-type-is-specific
| Rule id: |
ibm-content-type-is-specific |
| Description: |
The use of */* as a mimetype within a content field should be avoided
unless the API actually supports all content types.
If the API in fact supports all content types, this warning should be ignored.
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
requestBody:
content:
'*/*':
...
|
</tr>
| Compliant example: |
requestBody:
content:
'application/json':
...
'text/plain':
...
|
</table>
### ibm-define-required-properties
| Rule id: |
ibm-define-required-properties |
| Description: |
This rule verifies that for each property name included in a schema's required list,
that property must be defined within the schema.
The property could be defined in any of the following ways:
- within the schema's
properties field
- within one or more of the schemas listed in the
allOf field
- within each of the schemas listed in the
anyOf or oneOf field
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
required:
- thing_id
- thing_version
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
thing_version:
type: string
required:
- thing_id
- thing_version
|
</table>
### ibm-discriminator-property
| Rule id: |
ibm-discriminator-property |
| Description: |
This rule is used in conjunction with Spectral's oas3-schema rule to verify that a
discriminator object (if present) is defined properly within a schema.
This includes the following validations:
- The
discriminator field must be an object.
- The
discriminator object must have a field named propertyName that defines the name of the discriminator property.
- The
propertyName field must be of type string.
- The schema property whose name is specified with the
propertyName field must exist within the schema.
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schema:
Thing:
description: A Thing instance.
type: object
properties:
thing_id:
type: string
thing_version:
type: string
discriminator:
propertyName: thing_type
|
</tr>
| Compliant example: |
components:
schema:
Thing:
description: A Thing instance.
type: object
properties:
thing_type:
type: string
thing_id:
type: string
thing_version:
type: string
discriminator:
propertyName: thing_type
|
</table>
### ibm-dont-require-merge-patch-properties
| Rule id: |
ibm-dont-require-merge-patch-properties |
| Description: |
In order to adhere to the "merge-patch" semantics, the requestBody schema for a patch operation
with application/merge-patch+json requestBody content should not
define any required properties or specify a non-zero value for the minProperties field.
This rule verifies that "merge-patch" operations adhere to this requirement.
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
/v1/things/{thing_id}:
patch:
operationId: update_thing
requestBody:
content:
'application/merge-patch+json':
schema:
$ref: '#/components/schemas/ThingPatch'
components:
schemas:
ThingPatch:
type: object
required:
- name
- long_description
properties:
name:
description: The name of the Thing
type: string
long_description:
description: The long description of the Thing
|
</tr>
| Compliant example: |
paths:
/v1/things/{thing_id}:
patch:
operationId: update_thing
requestBody:
content:
'application/merge-patch+json':
schema:
$ref: '#/components/schemas/ThingPatch'
components:
schemas:
ThingPatch: <<< no longer defines any required properties
type: object
properties:
name:
description: The name of the Thing
type: string
long_description:
description: The long description of the Thing
|
</table>
### ibm-enum-casing-convention
| Rule id: |
ibm-enum-casing-convention |
| Description: |
This rule verifies that enum fields specified for string-type schema properties
contain values that follow a specific case convention, with the default being snake case. |
| Severity: |
error |
| OAS Versions: |
oas3 |
| Configuration: |
This rule can be configured to enforce a specific case convention for enum values.
To configure the rule, set the functionOptions field within the rule definition to be an object
that is the appropriate configuration to be used by Spectral's casing() function
[1]
to enforce the desired case convention for enum values.
The default configuration object provided in the rule definition is:
{
type: 'snake'
}
To enforce a different case convention for enum values, you'll need to
replace this rule with a new rule within your
custom ruleset and modify the configuration such that the value of the type field
specifies the desired case convention.
For example, to enforce camel case for enum values, the configuration object would look like this:
{
type: 'camel'
}
</td>
</tr>
|
| Non-compliant example:</td>
|
components:
schemas:
ThingType:
type: string
enum:
- thingType1
- thingType2
|
</tr>
| Compliant example: |
components:
schemas:
ThingType:
type: string
enum:
- thing_type_1
- thing_type_2
|
</table>
### ibm-error-content-type-is-json
| Rule id: |
ibm-error-content-type-is-json |
| Description: |
An error response likely returns application/json content and this rule warns when application/json
is not the content mimetype.
This rule should be ignored when the API actually returns an error response that is not application/json.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
responses:
400:
content:
'application/octet-stream':
...
|
</tr>
| Compliant example: |
responses:
400:
content:
'application/json':
...
|
</table>
### ibm-error-response-schemas
| Rule id: |
ibm-error-response-schemas |
| Description: |
This rule implements the guidance related to error response schemas found in the API Handbook.
Specifically, the following checks are performed against each schema associated with an error response:
- The error response schema should form a valid
error container model as
described by the API Handbook.
- The
errors property must be an array whose items field is a schema that forms a valid
error model
as described in the API Handbook.
- If present, the
target property must contain a valid
error target model
as described in the API Handbook.
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorContainer'
components:
schemas:
ErrorContainer:
description: 'An error response for an operation.'
type: object
properties:
error:
$ref: '#/components/schemas/Error'
trace:
description: 'The error trace information.'
type: string
format: uuid
Error:
description: 'An error response entry.'
type: object
properties:
code:
description: 'The error code.'
type: integer
message:
description: 'The error message.'
type: string
more_info:
description: 'Additional info about the error.'
type: string
|
</tr>
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorContainer'
components:
schemas:
ErrorContainer:
description: 'An error response for an operation.'
type: object
properties:
errors:
type: array
minItems: 0,
maxItems: 100,
description: 'The array of error entries associated with the error response',
items:
$ref: '#/components/schemas/Error'
trace:
description: 'The error trace information.'
type: string
format: uuid
}
}
},
Error:
description: 'An error response entry.'
type: object
properties:
code:
description: 'The error code.'
type: string
enum:
- 'bad_request'
- 'not_authorized'
- 'no_need_to_know'
},
message:
description: 'The error message.'
type: string
more_info:
description: 'Additional info about the error.'
type: string
|
</table>
### ibm-etag-header
| Rule id: |
ibm-etag-header |
| Description: |
This rule checks each path item (the object containing operations with keys 'get', 'post', 'delete', etc.) to make sure that
the path item's GET operation defines the ETag response header if it is, in fact, needed.
An ETag response header is needed if there are operations within the same
path item that support the If-Match or If-Not-Match header parameters.
The reasoning behind this rule is that if a given path has one or more operations in which the user needs
to provide a value for the If-Match or If-None-Match header parameters
(sometimes referred to as an "etag value"), then the API should provide a way for the user to obtain the etag value.
And the standard way for a service to provide an etag value to the user is by returning it as the ETag response header
within the GET operation's response.
</td>
</tr>
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things/{thing_id}':
parameters:
- name: thing_id
description: The id of the Thing.
in: path
required: true
schema:
type: string
get:
operationId: get_thing
responses:
'200':
description: 'Success response!'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingCollection'
delete:
operationId: delete_thing
parameters:
- name: 'If-Match'
description: The etag value associated with the Thing instance to be deleted.
in: header
required: true
schema:
type: string
responses:
'204':
description: 'Success response!'
|
</tr>
| Compliant example: |
paths:
'/v1/things/{thing_id}':
parameters:
- name: thing_id
description: The id of the Thing.
in: path
required: true
schema:
type: string
get:
operationId: get_thing
responses:
'200':
description: 'Success response!'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingCollection'
headers:
ETag:
description: The unique etag value associated with the instance that was retrieved.
schema:
type: string
delete:
operationId: delete_thing
parameters:
- name: 'If-Match'
description: The etag value associated with the Thing instance to be deleted.
in: header
required: true
schema:
type: string
responses:
'204':
description: 'Success response!'
|
</table>
### ibm-integer-attributes
| Rule id: |
ibm-integer-attributes |
| Description: |
This rule checks to make sure that integer schema properties comply with the API Handbook guidance. Specifically, the rule verifies that each integer schema property
defines the minimum and maximum fields, and also verifies that the format field (if defined)
is specified as int32 or int64.
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
description: A Thing instance.
type: object
properties:
thing_size:
description: The size of the Thing instance, in ml.
type: integer
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
description: A Thing instance.
type: object
properties:
thing_size:
description: The size of the Thing instance, in ml.
type: integer
minimum: 0
maximum: 1000
|
</table>
### ibm-major-version-in-path
| Rule id: |
ibm-major-version-in-path |
| Description: |
Each path defined within the API definition should include a path segment for the API major version,
of the form v<n>, and all paths should have the same API major version segment.
The API major version can appear in either the server URL or in each path entry. In the path entry, the first segment of the API's path must be the major version of the API.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
openapi: 3.0.1
info:
version: 1.0.0
...
paths:
/things:
...
|
</tr>
| Compliant example: |
openapi: 3.0.1
info:
version: 1.0.0
...
paths:
/v1/things:
...
|
</table>
### ibm-no-accept-header
| Rule id: |
ibm-no-accept-header |
| Description: |
Operations should not explicitly define the Accept header parameter.
Instead, the value of the Accept parameter is inferred from the responses field. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
paths:
'/v1/things':
get:
operationId: list_things
parameters:
- name: Accept
in: header
description: The expected content type within the response.
schema:
type: string
responses:
'200':
description: 'Success response!'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingCollection'
|
| Compliant example: |
paths:
'/v1/things':
get:
operationId: list_things
responses:
'200':
description: 'Success response!'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingCollection'
|
### ibm-no-ambiguous-paths
| Rule id: |
ibm-no-ambiguous-paths |
| Description: |
The path strings defined within an OpenAPI document must be unique and unambiguous.
In general, two paths are ambiguous if the following are true:
- the two paths contain the same number of path segments (e.g. /v1/foo, /v1/{foo})
- when comparing each of the respective path segments in each path string:
- both path segments are non-parameterized and are equal (e.g. 'foo' vs 'foo')
- one or the other of the path segments is parameterized (e.g. 'foo' vs '{foo_id}')
- both of the path segments are parameterized (e.g. '{foo_id}' vs '{id}')
</ul>
Here are examples of paths that are ambiguous despite being unique:
/v1/things/{thing_id}, /v1/things/{id}
/v1/things/{thing_id}, /v1/things/other_things
/{version}/things, /v1/{things}
</ul>
Each of the pairs of path strings above would be considered ambiguous.
</td>
</tr>
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
paths:
'/v1/things/{thing_id}':
...
'/v1/things/{foo_id}':
...
'/v1/things/other_things':
...
|
| Compliant example: |
paths:
'/v1/things/{thing_id}':
...
'/v1/foos/{foo_id}':
...
'/v1/things/{thing_id}/other_things':
...
|
</table>
### ibm-no-array-of-arrays
| Rule id: |
ibm-no-array-of-arrays |
| Description: |
Array schemas with items of type array should be avoided |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
requestBody:
content:
application/json:
schema:
type: array
items:
type: array
items:
type: string
|
</tr>
| Compliant example: |
requestBody:
content:
application/json:
schema:
type: array
items:
type: string
|
</table>
### ibm-no-array-responses
| Rule id: |
ibm-no-array-responses |
| Description: |
This rule checks to make sure that operations do not define an array as the top-level structure within a response.
The recommendation is to instead use an object with a property that contains the array.
This will allow you to expand the definition of the response body (e.g. add new properties) in a compatible way
in the future if needed.
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
get:
operationId: list_things
responses:
'200':
content:
schema:
type: array
items:
$ref: '#/components/schemas/Thing'
sample response body:
[ {"name": "thing-1"}, {"name": "thing-2"} ]
|
</tr>
| Compliant example: |
paths:
'/v1/things':
get:
operationId: list_things
responses:
'200':
content:
schema:
type: object
properties:
things:
type: array
items:
$ref: '#/components/schemas/Thing'
sample response body:
{"things": [ {"name": "thing-1"}, {"name": "thing-2"} ]}
</pre>
|
</table>
### ibm-no-authorization-header
| Rule id: |
ibm-no-authorization-header |
| Description: |
Operations should not explicitly define the Authorization header parameter.
Instead, the security object should be used to indicate the supported authentication
mechanisms.
The security object can be defined at an operation level (which would apply only to
that operation) or at a global level within the API definition (which would apply to all operations).
Within generated SDKs, the Authorization header will be managed automatically by the
built-in authenticator support.
Non-SDK users (those using curl, for example) can infer
the use of the Authorization header from the security object in the API definition
together with other documentation provided for the service.
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
get:
operationId: list_things
parameters:
- name: Authorization
in: header
description: The IAM access token in the form of a Bearer token.
schema:
type: string
pattern: '^Bearer .*$'
responses:
'200':
description: 'Success response!'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingCollection'
|
</tr>
| Compliant example: |
security:
- IAM: []
components:
securitySchemes:
IAM:
description: Service supports normal IAM-based authentication/authorization.
in: header
name: Authorization
type: apiKey
paths:
'/v1/things':
get:
operationId: list_things
responses:
'200':
description: 'Success response!'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingCollection'
|
</table>
### ibm-no-body-for-delete
| Rule id: |
ibm-no-body-for-delete [Deprecated] |
| Description: |
This rule checks each DELETE operation and will return a warning if the operation contains a requestBody.
This rule has been deprecated and is now disabled in the IBM Cloud Validation Ruleset. Please use the ibm-no-operation-requestbody rule instead.
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#/components/parameters/ThingIdParam'
delete:
operationId: delete_thing
requestBody:
description: 'The Thing instance to be deleted.'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
responses:
'204':
description: 'The thing was deleted'
|
</tr>
| Compliant example: |
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#/components/parameters/ThingIdParam'
delete:
operationId: delete_thing
responses:
'204':
description: 'The thing was deleted'
|
</table>
### ibm-no-circular-refs
| Rule id: |
ibm-no-circular-refs |
| Description: |
This rule checks to make sure that the API definition doesn't contain circular references.
A circular reference (or cycle) would be a $ref to some sort of object (e.g. a schema)
where traversing the referenced object's various sub-objects (e.g. schema properties, allOf/anyOf/oneOf lists,
"additionalProperties", "items", etc.) leads us to a $ref that is a reference to the original referenced object.
One example of a circular reference would be a schema "Foo" that contains a property "foo" that is
an instance of "Foo" itself. Another example would be a "Foo" schema that contains property
"bar" that is an instance of the "Bar" schema, and "Bar" contains a property "foo" that is an instance of the "Foo" schema.
Any reference to either "Foo" or "Bar" will be a circular reference.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Foo:
type: object
properties:
bar:
$ref: '#/components/schemas/Bar'
Bar:
type: object
properties:
foo:
$ref: '#/components/schemas/Foo'
|
</tr>
| Compliant example: |
components:
schemas:
Foo:
type: object
properties:
bar:
$ref: '#/components/schemas/Bar'
Bar:
type: object
properties:
foo_id: # include only the Foo instance's id,
type: string # not the entire Foo instance
|
</table>
### ibm-no-consecutive-path-parameter-segments
| Rule id: |
ibm-no-consecutive-path-parameter-segments |
| Description: |
This rule checks each path string in the API to detect the presence of two or more path segments that contain
a parameter reference, which is not allowed.
For example, the path /v1/foos/{foo_id}/{bar_id} is invalid and should probably be /v1/foos/{foo_id}/bars/{bar_id}.
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/foos/{foo_id}/{bar_id}':
parameters:
- $ref: '#/components/parameters/FooIdParam'
- $ref: '#/components/parameters/BarIdParam'
get:
operationId: get_foobar
...
|
</tr>
| Compliant example: |
paths:
'/v1/foos/{foo_id}/bars/{bar_id}':
parameters:
- $ref: '#/components/parameters/FooIdParam'
- $ref: '#/components/parameters/BarIdParam'
get:
operationId: get_foobar
...
|
</table>
### ibm-no-content-type-header
| Rule id: |
ibm-no-content-type-header |
| Description: |
Operations should not explicitly define the Content-Type header parameter.
Instead, the value of the Content-Type parameter is inferred from the requestBody field.
Note that the Content-Type header parameter is managed automatically by generated SDKs. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
parameters:
- name: Content-Type
in: header
description: The content type of the request body.
schema:
type: string
requestBody:
description: 'The new Thing instance'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
|
</tr>
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
requestBody:
description: 'The new Thing instance'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
responses:
'201':
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
|
</table>
### ibm-no-crn-path-parameters
| Rule id: |
ibm-no-crn-path-parameters |
| Description: |
This rule checks to make sure that there are no path parameters that are defined as a CRN (Cloud Resource Name) value.
In order to determine whether or not a path parameter is considered to be defined as a CRN value, this validation rule
will perform the following checks:
- The parameter's
name field contains "crn" (e.g. "resource_crn")
- The parameter's schema is defined with type=string, format=crn
- The parameter's schema is defined with a pattern field that starts with either "crn" or "^crn" (e.g. 'crn:[-0-9A-Fa-f]+')
- The parameter's
example field contains a CRN-like value (e.g. "crn:0afd-0138-2636")
- The parameter's
examples field contains an entry containing a CRN-like value, as in this example:
components:
parameters:
ThingIdParam:
name: thing_id
description: The id of the Thing instance
in: path
required: true
schema:
type: string
examples:
crn_example:
value: 'crn:0afd-0138-2636'
- The parameter schema's
example field contains a CRN-like value (e.g. "crn:0afd-0138-2636")
- The parameter's
description field contains either "CRN" or "Cloud Resource Name"
- The parameter schema's
description field contains either "CRN" or "Cloud Resource Name"
These checks are logically OR'd together, so that if any one or more of these checks
are true for a particular parameter, then a warning is raised for that parameter.
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
parameters:
ThingCrnParam:
name: thing_crn
description: The CRN associated with the Thing instance
in: path
required: true
schema:
type: string
format: crn
pattern: '^crn:[-0-9A-Fa-f]+$'
minLength: 5
maxLength: 32
|
</tr>
| Compliant example: |
components:
parameters:
ThingIdParam:
name: thing_id
description: The id associated with the Thing instance
in: path
required: true
schema:
type: string
format: identifier
pattern: '^id:[-0-9A-Fa-f]+$'
minLength: 5
maxLength: 32
|
</table>
### ibm-no-default-for-required-parameter
| Rule id: |
ibm-no-default-for-required-parameter |
| Description: |
Required parameters should not define a default value. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
parameters:
SortOrderParam:
name: sort_order
description: The sort order.
in: query
required: true
schema:
type: string
enum:
- asc
- desc
default: asc
|
</tr>
| Compliant example: |
components:
parameters:
SortOrderParam:
name: sort_order
description: The sort order.
in: query
required: true
schema:
type: string
enum:
- asc
- desc
|
</table>
### ibm-no-duplicate-description-with-ref-sibling
| Rule id: |
ibm-no-duplicate-description-with-ref-sibling |
| Description: |
This rule checks for instances where the "ref sibling" allOf pattern is used to override
the description of a referenced schema, but yet the overridden description is the same as that defined inside
the referenced schema.
Prior to OpenAPI 3.0, when defining a schema one could use a $ref along with additional attributes in order to
reference a named schema and also override those attributes defined within the referenced schema.
A common use of this pattern was to override a referenced schema's description with a more
specific description. Here is an example (a swagger 2.0 fragment):
definitions:
PageLink:
description: 'A link to a page of results' <<< general description
type: object
properties:
href:
description: 'The URL string pointing to a specific page of results'
type: string
ResourceCollection:
description: 'A collection of resources returned by the list_resources operation'
type: object
properties:
first:
$ref: '#/definitions/PageLink'
description: 'A link to the first page of results' <<< more specific description
next:
$ref: '#/definitions/PageLink'
description: 'A link to the next page of results' <<< more specific description
In this example, the "first" and "next" properties are given specific descriptions that indicate they point to
the first and next page of results, respectively.
Starting with OpenAPI 3.0, one can no longer use this pattern. If a schema definition contains the $ref attribute,
then no other attributes are allowed to be defined alongsize it. So to work around this restriction,
API authors typically use the "ref sibling" allOf pattern. The above example might look like this:
components:
schemas:
PageLink:
description: 'A link to a page of results' <<< general description
type: object
properties:
href:
description: 'The URL string pointing to a specific page of results'
type: string
ResourceCollection:
description: 'A collection of resources returned by the list_resources operation'
type: object
properties:
first:
allOf:
- $ref: '#/components/schemas/PageLink'
- description: 'A link to the first page of results' <<< more specific description
next:
description: 'A link to the next page of results' <<< more specific description
allOf:
- $ref: '#/components/schemas/PageLink'
In this example the "first" property uses an allOf with two list elements, where the second list element schema overrides
the description of the PageLink schema. The "next" property is defined using a variation of the "ref sibling" allOf pattern
where the overridden description is defined directly as an attribute of the "next" schema itself rather than in the
second allOf list element. Both are considered to be examples of the "ref sibling" allOf pattern.
This rule specifically looks for instances of this pattern where the overridden description is the same as the
description defined within the referenced schema, thus making the use of the "ref sibling" pattern unnecessary.
Here is an example of this:
components:
schemas:
PageLink:
description: 'A link to a page of results' <<< general description
type: object
properties:
href:
description: 'The URL string pointing to a specific page of results'
type: string
ResourceCollection:
description: 'A collection of resources returned by the list_resources operation'
type: object
properties:
page_link:
allOf:
- $ref: '#/components/schemas/PageLink'
- description: 'A link to a page of results' <<< duplicate description
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
PageLink:
description: 'A link to a page of results'
type: object
properties:
href:
description: 'The URL string pointing to a specific page of results'
type: string
ResourceCollection:
description: 'A collection of resources returned by the list_resources operation'
type: object
properties:
page_link:
allOf:
- $ref: '#/components/schemas/PageLink'
- description: 'A link to a page of results'
|
</tr>
| Compliant example: |
components:
schemas:
PageLink:
description: 'A link to a page of results'
type: object
properties:
href:
description: 'The URL string pointing to a specific page of results'
type: string
ResourceCollection:
description: 'A collection of resources returned by the list_resources operation'
type: object
properties:
page_link:
$ref: '#/components/schemas/PageLink'
|
</table>
### ibm-no-if-modified-since-header
| Rule id: |
ibm-no-if-modified-since-header |
| Description: |
The API Handbook
recommends against the use of the If-Modified-Since and If-Unmodified-Since header parameters.
Operations should support If-Match and If-None-Match headers instead.
This rule warns about operations that support the If-Modified-Since header parameter.
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#components/parameters/ThingIdParam'
get:
operationId: get_thing
parameters:
- name: If-Modified-Since
in: header
description: |-
The operation will succeed only if the resource has been last modified
after the date specified for this header parameter.
schema:
type: string
responses:
'200':
description: 'Resource was retrieved successfully!'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
'412':
description: 'Resource has not been modified after If-Modified-Since date.'
|
| Compliant example: |
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#components/parameters/ThingIdParam'
get:
operationId: get_thing
parameters:
- name: If-None-Match
in: header
description: |-
The operation will succeed only if the resource's current ETag value
does not match the value specified for this header parameter.
schema:
type: string
responses:
'200':
description: 'Resource was retrieved successfully!'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
'412':
description: 'Resource current ETag matches If-None-Match value.'
|
</table>
### ibm-no-if-unmodified-since-header
| Rule id: |
ibm-no-if-unmodified-since-header |
| Description: |
The API Handbook
recommends against the use of the If-Modified-Since and If-Unmodified-Since header parameters.
Operations should support If-Match and If-None-Match headers instead.
This rule warns about operations that support the If-Unmodified-Since header parameter.
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#components/parameters/ThingIdParam'
delete:
operationId: delete_thing
parameters:
- name: If-Unmodified-Since
in: header
description: |-
The operation will succeed only if the resource has not been modified
after the date specified for this header parameter.
schema:
type: string
responses:
'204':
description: 'Resource was deleted successfully!'
'412':
description: 'Resource was last modified after the If-Unmodified-Since date.'
|
| Compliant example: |
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#components/parameters/ThingIdParam'
delete:
operationId: delete_thing
parameters:
- name: If-Match
in: header
description: |-
The operation will succeed only if the resource's current ETag value
matches the value specified for this header parameter.
schema:
type: string
responses:
'204':
description: 'Resource was deleted successfully!'
'412':
description: 'Resource current ETag value does not match the If-Match value.'
|
</table>
### ibm-no-nullable-properties
| Rule id: |
ibm-no-nullable-properties |
| Description: |
The API Handbook
provides guidance related to the use of nullable schema properties. Specifically, the API Handbook
allows nullable schema properties to be defined only within JSON merge-patch request body schemas.
This rule ensures that nullable properties are not defined elsewhere.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
thing_name:
type: string
thing_size:
type: integer
thing_type:
type: string
nullable: true <<< not valid in a response schema
ThingPatch:
type: object
properties:
thing_name:
type: string
nullable: true <<< valid only in a merge-path requestBody schema
thing_size:
type: integer
nullable: true <<< valid only in a merge-path requestBody schema
thing_type:
type: string
nullable: true <<< valid only in a merge-path requestBody schema
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#/components/parameters/ThingIdParameter'
patch:
operationId: update_thing
requestBody:
description: An object used to modify an existing Thing instance
content:
application/merge-patch+json:
schema:
$ref: '#/components/schemas/ThingPatch'
responses:
'200':
description: Thing instance was updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
thing_name:
type: string
thing_size:
type: integer
thing_type: <<< property is no longer nullable
type: string
ThingPatch:
type: object
properties:
thing_name:
type: string
nullable: true
thing_size:
type: integer
nullable: true
thing_type:
type: string
nullable: true
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#/components/parameters/ThingIdParameter'
patch:
operationId: update_thing
requestBody:
description: An object used to modify an existing Thing instance
content:
application/merge-patch+json:
schema:
$ref: '#/components/schemas/ThingPatch'
responses:
'200':
description: Thing instance was updated successfully
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
|
</table>
### ibm-no-operation-requestbody
| Rule id: |
ibm-no-operation-requestbody |
| Description: |
The API Handbook
provides guidance related to the use of various HTTP methods.
In particular, the API Handbook discourages the use of a requestBody
with DELETE, GET, HEAD and OPTIONS operations.
This rule ensures that these operations do not define a requestBody.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Configuration: |
This rule supports a configuration that specifies the set of HTTP methods that are checked
for a requestBody.
The default configuration object provided with the rule is:
{
httpMethods: ['delete', 'get', 'head', 'options']
}
To configure the rule with a different set of HTTP methods, you'll need to
replace this rule with a new rule within your
custom ruleset and modify the configuration such that the value of the httpMethods field
specifies the desired set of HTTP methods to be checked.
For example, to enforce the rule for DELETE, HEAD and OPTIONS operations, the configuration object would look like this:
{
httpMethods: ['delete', 'head', 'options']
}
</td>
</tr>
|
| Non-compliant example:</td>
|
paths:
'/v1/things/search':
get:
operationId: search_things
requestBody:
description: 'An object containing the search-related properties: filter, sort'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingSearchRequest'
responses:
'200':
description: 'Search completed successfully'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingSearchResponse'
|
</tr>
| Compliant example: |
paths:
'/v1/things/search':
get:
parameters:
- name: filter
in: query
description: The search filter to use.
schema:
type: string
- name: sort
in: query
description: The sort order.
schema:
type: string
operationId: search_things
responses:
'200':
description: 'Search completed successfully'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingSearchResponse'
|
</table>
### ibm-no-optional-properties-in-required-body
| Rule id: |
ibm-no-optional-properties-in-required-body |
| Description: |
This rule scrutinizes optional request bodies because in most cases, they should be required.
Specifically, this rule examines the schemas associated with optional request bodies and
if there are required properties, then it is likely that the API author intended for the
request body to be required.
This rule is deprecated. Please use the ibm-no-required-properties-in-optional-body rule instead.
|
| Severity: |
off |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
requestBody:
required: false
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing' # Assume "Thing" schema has required properties
|
</tr>
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
requestBody:
required: true
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing' # Assume "Thing" schema has required properties
|
</table>
### ibm-no-ref-in-example
| Rule id: |
ibm-no-ref-in-example |
| Description: |
Within an OpenAPI document, the $ref field may appear within an examples field, but it is not valid within an example field. This rule checks to make sure that $ref is not used within an example field. |
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
/v1/things:
post:
operationId: create_thing
description: Create a new Thing instance.
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
example:
$ref: '#/components/examples/ThingExample'
|
</tr>
| Compliant example: |
paths:
/v1/things:
post:
operationId: create_thing
description: Create a new Thing instance.
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
example:
name: 'Thing1'
description: 'An example Thing object'
|
</table>
### ibm-no-required-properties-in-optional-body
| Rule id: |
ibm-no-required-properties-in-optional-body |
| Description: |
This rule scrutinizes optional request bodies because in most cases, they should be required.
Specifically, this rule examines the schemas associated with optional request bodies and
if there are required properties, then it is likely that the API author intended for the
request body to be required.
|
| Severity: |
info |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
requestBody:
required: false
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing' # Assume "Thing" schema has required properties
|
</tr>
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
requestBody:
required: true
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing' # Assume "Thing" schema has required properties
|
</table>
### ibm-no-space-in-example-name
| Rule id: |
ibm-no-space-in-example-name |
| Description: |
The name of an entry in an examples field should not contain a space. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
/v1/things:
post:
operationId: create_thing
description: Create a new Thing instance.
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
examples:
'Create Thing Example':
value:
thing_id: 1ac38d2z89
thing_type: type1
responses:
...
|
</tr>
| Compliant example: |
paths:
/v1/things:
post:
operationId: create_thing
description: Create a new Thing instance.
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
examples:
CreateThingExample:
value:
thing_id: 1ac38d2z89
thing_type: type1
responses:
...
|
</table>
### ibm-no-superfluous-allof
| Rule id: |
ibm-no-superfluous-allof |
| Description: |
If a schema contains only a single-element allOf, the allOf can be considered superfluous and can be removed. This rule checks for these unnecessary allOf attributes. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
properties:
foo_ref:
allOf:
- $ref: '#/components/schemas/Foo'
<
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
properties:
foo_ref:
$ref: '#/components/schemas/Foo'
|
</table>
### ibm-no-unsupported-keywords
| Rule id: |
ibm-no-unsupported-keywords |
| Description: |
This rule checks for the presence of specific keywords within an OpenAPI 3.1.x document that are not yet supported
by IBM's SDK-related tooling - specifically the jsonSchemaDialect and
webhooks keywords. An error is logged if either of these keywords is found in the document.
|
| Severity: |
error |
| OAS Versions: |
oas3_1 |
| Non-compliant example:</td>
|
openapi: 3.1.0
info:
title: Thing Service
description: A service that manages Things
version: 1.0.0
jsonSchemaDialect: 'https://spec.openapis.org/oas/3.1/dialect/base' <<< not supported
webhooks: <<< not supported
newThingTypeAvailable:
post:
description: |-
A callback-like operation to be implemented by the client so that it
can be informed of a new type of Thing supported by the server.
requestBody:
description: 'A new type of Thing can now be created on the server.'
content:
application/json:
schema:
type: object,
properties:
thing_type:
description: 'The new type value that can be used to create a Thing instance.'
type: string
responses:
'200':
description: |-
Return a 200 status code to the server to indicate that the new Thing type
was received successfully by the client.
|
</tr>
| Compliant example: |
openapi: 3.1.0
info:
title: Thing Service
description: A service that manages Things
version: 1.0.0
|
</table>
### ibm-openapi-tags-used
| Rule id: |
ibm-openapi-tags-used |
| Description: |
This rule verifies that each tag (defined in the tags field) is referenced by one or more operations. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
tags:
- name: Things
description: Operations related to Things.
- name: UnusedTag
description: This tag is not used.
paths:
'/v1/things':
post:
operationId: create_thing
description: Create a new Thing instance.
summary: Create a Thing
tags:
- Things
|
</tr>
| Compliant example: |
tags:
- name: Things
description: Operations related to Things.
paths:
'/v1/things':
post:
operationId: create_thing
description: Create a new Thing instance.
summary: Create a Thing
tags:
- Things
|
</table>
### ibm-operation-responses
| Rule id: |
ibm-operation-responses |
| Description: |
This rule verifies that each operation has a responses field.
|
| Severity: |
error |
| OAS Versions: |
oas3_1 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
|
</tr>
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
responses:
'201':
description: 'The Thing instance was created successfully'
content:
application/json:
schema:
type: object
properties:
thing_id:
type: string
thing_description:
type: string
|
</table>
### ibm-operation-summary
| Rule id: |
ibm-operation-summary |
| Description: |
This rule verifies that each operation has a non-empty summary.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
description: Create a new Thing instance.
|
</tr>
| Compliant example: |
paths:
'/v1/things':
get:
operationId: create_thing
description: Create a new Thing instance.
summary: Create a Thing
|
</table>
### ibm-operation-summary-length
| Rule id: |
ibm-operation-summary-length |
| Description: |
This rule verifies that each operation's summary is at most 80 characters in length,
per guidance in the API Handbook.
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
description: Create a new Thing instance.
summary: Create a shiny, brand new, hot-off-the-press instance of the standard Thing resource
|
</tr>
| Compliant example: |
paths:
'/v1/things':
get:
operationId: create_thing
description: Create a new Thing instance.
summary: Create a Thing
|
</table>
### ibm-operationid-casing-convention
| Rule id: |
ibm-operationid-casing-convention |
| Description: |
Operation ids should follow a specific case convention, with the default being snake case. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Configuration: |
This rule can be configured to enforce a specific case convention for operationId values.
To configure the rule, set the functionOptions field within the rule definition to be an object
that is the appropriate configuration to be used by Spectral's casing() function
[1]
to enforce the desired case convention for operationId values.
The default configuration object provided in the rule definition is:
{
type: 'snake'
}
To enforce a different case convention for operationId values, you'll need to
replace this rule with a new rule within your
custom ruleset and modify the configuration such that the value of the type field
specifies the desired case convention.
For example, to enforce camel case for operation ids, the configuration object would look like this:
{
type: 'camel'
}
</td>
</tr>
|
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: createThing
|
</tr>
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
|
</table>
### ibm-operationid-naming-convention
| Rule id: |
ibm-operationid-naming-convention |
| Description: |
Operation ids should follow a naming convention using standard, predictable verbs.
For example, create_thing would be preferred over manufacture_thing
when deciding on an operationId for the POST /v1/things operation.
Likewise, for the GET /v1/things/{thing_id} operation, we might prefer
get_thing over retrieve_thing for the operationId.
This rule will analyze the operations, looking for operationId values that are not using the recommended verbs. Furthermore it can also validate the complete name of the operation id by comparing it to the path segments.
</td>
</tr>
|
| Configuration: |
This rule can be configured to validate the complete name of the operation id, or only the verb it begins with.
The default configuration object provided in the rule definition is:
{
strict: true
}
To switch off the complete name validation and only validate the verbs the operation ids begin with, you'll need to
replace this rule with a new rule within your
custom ruleset and modify the configuration such that the value of the strict field to false
{
strict: false
}
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: manufacture_thing
description: Create a new Thing instance.
summary: Create a Thing
get:
operationId: list_thing
description: List all Thing instances.
summary: List Thing
'/v1/things/{thing_id}':
get:
operationId: retrieve_thing
description: Get a Thing instance.
summary: Get a Thing
|
</tr>
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
description: Create a new Thing instance.
summary: Create a Thing
get:
operationId: list_things
description: List all Thing instances.
summery: List Things
'/v1/things/{thing_id}':
get:
operationId: get_thing
description: Get a Thing instance.
summary: Get a Thing
|
</table>
### ibm-pagination-style
| Rule id: |
ibm-pagination-style |
| Description: |
This rule verifies that list-type operations implement pagination correctly per the guidelines in the
API Handbook.
An operation is recognized as a paginated list-type operation if all of the following are true:
- The path doesn't end in a path segment that is a path parameter reference
(e.g.
/v1/things vs /v1/things/{thing_id}).
- The operation is a get.
- The operation's response schema is an object containing an array property.
- The operation defines either the
offset query parameter or a page-token type
query parameter whose name is one of the following: start(preferred),
token, cursor, page, or page_token.
If an operation is recognized as a paginated list-type operation, then the following checks are
performed:
- If the operation has a
limit query parameter, then it must be of type integer,
optional, and have default and maximum values defined for it [1,
2].
- If the operation has an
offset query parameter, then it must be of type integer and
optional [3].
- If the operation has an
offset query parameter, then it must also have a limit
query parameter [4].
This is because the presence of the offset parameter indicates that the offset/limit style pagination is being used.
- If the operation has a page-token type query parameter, then it must be of type
string
and optional, and its name should be start [5].
- If the operation has a
limit query parameter, then the response body schema must
contain a limit schema property that is of type integer and required
[6,
7].
- If the operation has an
offset query parameter, then the response body schema must
contain an offset schema property that is of type integer and required
[8].
- If the operation's response body schema contains a
total_count property, then it must
be of type integer and required
[9,
10].
- The operation's response body schema should contain properties named
first, last, previous and next that provide links to the first, last,
previous and next page of results, respectively.
Each of these properties should be defined as an object with a property named href
of type string which contains the appropriate request URL string to be used to obtain
that page of results [11].
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
n/a
|
</tr>
| Compliant example: |
n/a
|
</table>
### ibm-parameter-casing-convention
| Rule id: |
ibm-parameter-casing-convention |
| Description: |
This rule verifies that each parameter name complies with the casing convention associated with that parameter's type.
For example, the default casing convention for query parameters is snake-case (e.g. my_query_param), the default for path parameters
is snake-case (e.g. my_path_param), and the default casing convention for header params is kebab-separated pascal-case with provision for capitalized abbreviations (e.g. IBM-CustomHeader-Name).
These default casing conventions constitute the default configuration for the rule, although the rule's configuration can be modified to
fit your needs (see below).
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Configuration: |
This rule can be configured to enforce specific case conventions for each parameter type.
To configure the rule, set the functionOptions field within the rule definition to be an object
with keys that represent the different parameter types to be checked for proper case conventions
('query', 'path', and 'header'). The value associated with each entry should be an object that is the
appropriate configuration to be used by either Spectral's casing() function
[1]
or pattern() function [2]
(for greater control over the case convention check) to enforce the desired case convention for that parameter type.
Additionally, you can define custom messages in the form "{parameter-type}Message".
The default configuration object provided in the rule definition is:
{
query: {
type: 'snake',
separator: {
char: '.'
}
},
path: {
type: 'snake'
},
// Spectral casing convention types aren't robust enough to handle
// the complexity of headers, so we define our own kebab/pascal case regex.
header: {
match: '/^[A-Z]+[a-z0-9]*-*([A-Z]+[a-z0-9]*-*)*$/',
},
headerMessage: 'Header parameter names must be kebab-separated pascal case',
}
This enforces:
- Query parameter names to be snake-case, while also allowing "." within the name
- Path parameter names to be snake-case
- Header parameter names to be in http header canonical form, which amounts to
pascal casing with a hyphen ("-") separating the words
(e.g. X-My-Header).
To disable the case convention checks for a particular parameter type, simply remove
the entry for that parameter type from the configuration object.
If you want to use a different configuration for this rule other than the default configuration
mentioned above, you'll need to
replace this rule with a new rule within your
custom ruleset and modify the configuration appropriately for your needs.
For example, to disable the case convention checks on header parameter names, while enforcing camel-case conventions
on query and path parameter names, the configuration object would look like this:
{
query: {
type: 'camel'
},
path: {
type: 'camel'
}
}
</td>
</tr>
|
| Non-compliant example:</td>
|
components:
parameters:
SortOrderParam:
name: sortOrder << camel-case
description: The sort order.
in: query
required: false
schema:
type: string
enum:
- asc
- desc
default: asc
|
</tr>
| Compliant example: |
components:
parameters:
SortOrderParam:
name: sort_order << snake-case
description: The sort order.
in: query
required: false
schema:
type: string
enum:
- asc
- desc
default: asc
|
</table>
### ibm-parameter-description
| Rule id: |
ibm-parameter-description |
| Description: |
Parameters should have a non-empty description. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
parameters:
SortOrderParam:
name: sort_order
in: query
required: false
schema:
type: string
enum:
- asc
- desc
default: asc
|
</tr>
| Compliant example: |
components:
parameters:
SortOrderParam:
name: sort_order
description: An optional ordering to be performed on the results that are returned.
in: query
required: false
schema:
type: string
enum:
- asc
- desc
default: asc
|
</table>
### ibm-parameter-order
| Rule id: |
ibm-parameter-order |
| Description: |
It is a good practice to list the parameters within an operation such that all required parameters are
listed first, then any optional parameters.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
get:
operationId: list_things
description: List the set of Things.
summary: List Things
parameters:
- name: offset
required: false
in: query
schema:
type: integer
- name: limit
required: false
in: query
schema:
type: integer
- name: filter
required: true
in: query
schema:
type: string
|
</tr>
| Compliant example: |
paths:
'/v1/things':
get:
operationId: list_things
description: List the set of Things.
summary: List Things
parameters:
- name: filter
required: true
in: query
schema:
type: string
- name: offset
required: false
in: query
schema:
type: integer
- name: limit
required: false
in: query
schema:
type: integer
|
</table>
### ibm-parameter-schema-or-content
| Rule id: |
ibm-parameter-schema-or-content |
| Description: |
Each parameter must provide either a schema or content object. |
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
parameters:
- name: param1
in: query
description: query param
|
</tr>
| Compliant example: |
parameters:
- name: param1
in: query
description: query param
schema:
type: string
|
</table>
### ibm-patch-request-content-type
| Rule id: |
ibm-patch-request-content-type |
| Description: |
The API Handbook
recommends that PATCH operations contain request bodies that support only content types
application/json-patch+json and application/merge-patch+json.
This rule verifies that each PATCH operation complies with this recommendation.
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#/components/parameters/ThingIdParam'
patch:
operationId: update_thing
description: Update a Thing instance.
requestBody:
content:
application/json:
schema:
- $ref: '#/components/schemas/Thing'
responses:
'200':
description: 'Thing updated successfully!'
|
</tr>
| Compliant example: |
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#/components/parameters/ThingIdParam'
patch:
operationId: update_thing
description: Update a Thing instance.
requestBody:
content:
application/merge-patch+json:
schema:
- $ref: '#/components/schemas/Thing'
responses:
'200':
description: 'Thing updated successfully!'
|
</table>
### ibm-path-segment-casing-convention
| Rule id: |
ibm-path-segment-casing-convention |
| Description: |
Path segments must follow a specific case convention, with the default being snake case. |
| Severity: |
error |
| OAS Versions: |
oas3 |
| Configuration: |
This rule's default configuration will enforce snake case for path segments, but the rule can be configured
to enforce a different case convention if desired.
To enforce a different case convention for path segments, you'll need to
replace this rule with a new rule within your
custom ruleset and modify the configuration such that the value of the type field
specifies the desired case convention.
For example, to enforce camel case for path segments, the configuration object would look like this:
{
type: 'camel'
}
</td>
</tr>
|
| Non-compliant example:</td>
|
paths:
'/v1/someThings/{thing_id}':
|
</tr>
| Compliant example: |
paths:
'/v1/some_things/{thing_id}':
|
</table>
### ibm-pattern-properties
| Rule id: |
ibm-pattern-properties |
| Description: |
This rule enforces certain restrictions related to the use of the patternProperties field
within a schema:
- The
patternProperties field must be an object with exactly one entry.
- The
patternProperties and additionalProperties fields are mutually exclusive within a particular schema.
- The
patternProperties field must contain a regular expression anchored by ^ and $.
</ul>
</tr>
| Severity: |
error |
| OAS Versions: |
oas3_1 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
type: object
properties:
id:
type: string
metadata:
description: additional info about the thing
type: object
patternProperties:
'^foo.*$':
type: string
'^bar.*$':
type: integer
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
id:
type: string
metadata:
description: additional info about the thing
type: object
patternProperties:
'^(foo|bar).*$':
type: string
|
</table>
### ibm-precondition-headers
| Rule id: |
ibm-precondition-headers |
| Description: |
Operations that return a 412 status code must support at least one of the following header parameters: If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since.
For more details, please see the API Handbook section on
Conditional headers. |
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#components/parameters/ThingIdParam'
get:
operationId: get_thing
responses:
'200':
description: 'Resource was retrieved successfully!'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
'412':
description: 'Resource current ETag matches If-None-Match value.'
|
</tr>
| Compliant example: |
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#components/parameters/ThingIdParam'
get:
operationId: get_thing
parameters:
- name: If-None-Match
in: header
description: |-
The operation will succeed only if the resource's current ETag value
does not match the value specified for this header parameter.
schema:
type: string
responses:
'200':
description: 'Resource was retrieved successfully!'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
'412':
description: 'Resource current ETag matches If-None-Match value.'
|
</table>
### ibm-prefer-token-pagination
| Rule id: |
ibm-prefer-token-pagination |
| Description: |
As per the API Handbook guidance on pagination, paginated list operations should use token-based pagination, rather than offset/limit pagination, wherever feasible. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things/':
get:
operationId: list_things
parameters:
- name: offset
in: query
description: 'The offset of the first item to return.'
required: false
schema:
type: integer
format: int32
minimum: 0
- name: limit
in: query
description: 'The number of items to return per page.'
required: false
schema:
type: integer
format: int32
minimum: 0
maximum: 100
default: 10
responses:
'200':
description: 'Resources retrieved successfully!'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingCollection'
'400':
description: 'List operation failed.'
|
</tr>
| Compliant example: |
paths:
'/v1/things/':
get:
operationId: list_things
parameters:
- name: start
in: query
description: 'The token representing the first item to return.'
required: false
schema:
type: string
minLength: 1
maxLength: 64
pattern: '[a-zA-Z0-9 ]+'
- name: limit
in: query
description: 'The number of items to return per page.'
required: false
schema:
type: integer
format: int32
minimum: 0
maximum: 100
default: 10
responses:
'200':
description: 'Resources retrieved successfully!'
content:
application/json:
schema:
$ref: '#/components/schemas/ThingCollection'
'400':
description: 'List operation failed.'
|
</table>
### ibm-property-attributes
| Rule id: |
ibm-property-attributes |
| Description: |
This rule performs the following checks on schemas and schema properties:
- Numeric schemas (type=integer, type=number):
-
minimum must not be greater than maximum.
minimum must not be defined for a schema type other than integer or number.
maximum must not be defined for a schema type other than integer or number.
multipleOf must not be defined for a schema type other than integer or number.
exclusiveMaximum must not be defined for a schema type other than integer or number.
exclusiveMinimum must not be defined for a schema type other than integer or number.
- Object schemas (type=object):
-
minProperties must not be greater than maxProperties.
minProperties must not be defined for a schema type other than object.
maxProperties must not be defined for a schema type other than object.
additionalProperties must not be defined for a schema type other than object.
properties must not be defined for a schema type other than object.
required must not be defined for a schema type other than object.
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
type: object
properties:
thing_size:
type: integer,
minimum: 5
maximum: 4
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_size:
type: integer,
minimum: 4
maximum: 5
|
</table>
### ibm-property-casing-convention
| Rule id: |
ibm-property-casing-convention |
| Description: |
Schema property names should follow a specific case convention, with the default being snake case. |
| Severity: |
error |
| OAS Versions: |
oas3 |
| Configuration: |
This rule can be configured to enforce a specific case convention for schema property names.
To configure the rule, set the functionOptions field within the rule definition to be an object
that is the appropriate configuration to be used by Spectral's casing() function
[1]
to enforce the desired case convention for property names.
The default configuration object provided in the rule definition is:
{
type: 'snake'
}
To enforce a different case convention for property names, you'll need to
replace this rule with a new rule within your
custom ruleset and modify the configuration such that the value of the type field
specifies the desired case convention.
For example, to enforce camel case for property names, the configuration object would look like this:
{
type: 'camel'
}
</td>
</tr>
|
| Non-compliant example:</td>
|
components:
schemas:
Thing:
type: object
properties:
thingId:
type: string
thingType:
type: string
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
thing_type:
type: string
|
</table>
### ibm-property-consistent-name-and-type
| Rule id: |
ibm-property-consistent-name-and-type |
| Description: |
Like-named schema properties (from different schemas) should have the same type to ensure consistency
throughout the API definition.
This rule is disabled by default. Enable it in your Spectral config file to utilize this validation.
|
| Severity: |
off |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
type: object
properties:
name:
description: The name of the Thing.
type: string
OtherThing:
type: object
properties:
name:
description: The name of the OtherThing.
type: integer # The property 'name' should use consistent types throughout the API
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
name:
description: The name of the Thing.
type: string
OtherThing:
type: object
properties:
name:
description: The name of the OtherThing.
type: string
|
</table>
### ibm-property-description
| Rule id: |
ibm-property-description |
| Description: |
Schema properties should have a non-empty description. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
thing_type:
type: string
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_id:
description: The ID associated with the Thing instance.
type: string
thing_type:
description: The type associated with the Thing instance.
type: string
|
</table>
### ibm-redirect-response-body
| Rule id: |
ibm-redirect-response-body |
| Description: |
This rule performs a few different checks on the operation redirect response bodies based on status codes:
- Regarding
30x responses a response body should only accompany any 301, 302, 305, 307.
- If a response body is provided for a 30x response, it must contain the following fields:
code, target and message.
- For a 30x response the code field must contain one of the following values for redirect code and nothing else:
forwarded, resolved, moved, remote_region, remote_account, version_mismatch.
References:
</td>
</tr>
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
description: 'Create a Thing instance.'
responses:
'301':
description: 'Only partial data'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
code: 'remote_region'
message: 'The requested resource is in a different region'
target:
crn: 'crn:v1:bluemix:public:is:us-south-1:a/aa2432b1fa4d4ace891e9b80fc104e34::share:r134-a0c07083-f411-446c-9316-7b08d6448c86'
href: 'https://us-south.iaas.cloud.ibm.com/v1/shares/r134-a0c07083-f411-446c-9316-7b08d6448c86'
id: 'r134-a0c07083-f411-446c-9316-7b08d6448c86'
name: 'my-share'
remote:
region:
href: 'https://us-east.iaas.cloud.ibm.com/v1/regions/us-south'
name: 'us-south'
resource_type: 'region'
resource_type: 'share'
|
</tr>
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
description: 'Create a Thing instance.'
responses:
'301':
description: 'Only partial data'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
code: 'remote'
|
</tr>
</table>
### ibm-ref-pattern
| Rule id: |
ibm-ref-pattern |
| Description: |
This rule checks each $ref value to make sure it follows the correct pattern based on
the type of object it references. For example, a reference to a schema should follow the pattern
#/components/schemas/<schema-name>.
Here is the full set of valid patterns for $ref values:
#/components/callbacks/<name>
#/components/examples/<name>
#/components/headers/<name>
#/components/links/<name>
#/components/parameters/<name>
#/components/requestBodies/<name>
#/components/responses/<name>
#/components/schemas/<name>
#/components/securitySchemes/<name>
The validator uses the $ref property's location within the API definition
to determine the type of object being referenced. For example, if the
$ref property is found where a parameter object is expected, then the validator assumes
that the $ref is referencing a parameter object, and that the reference should follow
the pattern #/components/parameters/<param-name>.
Incidentally, this rule also has the effect of ensuring that various types of objects are defined in their
proper locations within the API definition's componentsfield.
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Foo:
type: object
properties:
bar:
$ref: '#/definitions/Bar'
definitions:
Bar:
type: object
properties:
bar:
type: string
|
</tr>
| Compliant example: |
components:
schemas:
Foo:
type: object
properties:
bar:
$ref: '#/components/schemas/Bar'
Bar:
type: object
properties:
bar:
type: string
|
</table>
### ibm-request-and-response-content
| Rule id: |
ibm-request-and-response-content |
| Description: |
Each request body and non-204 response should have a content field. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
responses:
200:
description: 'Success response!'
|
</tr>
| Compliant example: |
responses:
200:
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
|
</table>
### ibm-requestbody-is-object
| Rule id: |
ibm-requestbody-is-object |
| Description: |
Each non-form-based request body should be defined as an object. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
requestBody:
content:
application/json:
schema:
type: string
|
</tr>
| Compliant example: |
requestBody:
content:
application/json:
schema:
type: object
properties:
prop1:
type: string
|
</table>
### ibm-requestbody-name
| Rule id: |
ibm-requestbody-name |
| Description: |
The x-codegen-request-body-name extension can be set on an operation to provide a language-agnostic
name for any body parameter that might appear within generated SDK code.
For operations that support multipart-form-based request body content, this isn't necessary since the
names of the form parameters are inferred from the property names within the request body schema.
However, for operations that support other non-form-based request body content (json-based and non-json-based content alike),
it is a good practice to provide the request body name via the extension, especially in situations where there is no other
way to infer a logical name for the operation's body parameter.
This rule analyzes each operation to determine if a request body name is needed, and if so, checks to make sure
that the x-codegen-request-body-name extension is set on the operation.
This rule is disabled by default. Enable it in your Spectral config file to utilize this validation.
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/logs':
post:
operationId: upload_logfile
requestBody:
content:
'application/octet-stream':
schema:
type: string
format: binary
|
</tr>
| Compliant example: |
paths:
'/v1/logs':
post:
operationId: upload_logfile
x-code-gen-request-body-name: log_file <<<
requestBody:
content:
'application/octet-stream':
schema:
type: string
format: binary
|
</table>
### ibm-required-array-properties-in-response
| Rule id: |
ibm-required-array-properties-in-response |
| Description: |
The IBM Cloud API Handbook
states that within a response body, an array property MUST NOT be optional.
This validation rule checks each schema used within a response to make sure each array property is defined as required
and not optional.
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/thing':
get:
operationId: list_things
responses:
200:
content:
'application/json':
schema:
$ref: '#/components/schemas/ThingCollection'
components:
schemas:
ThingCollection:
type: object
properties:
things: << array property is optional
type: array
items:
$ref: '#/components/schemas/Thing'
|
</tr>
| Compliant example: |
paths:
'/v1/thing':
get:
operationId: list_things
responses:
200:
content:
'application/json':
schema:
$ref: '#/components/schemas/ThingCollection'
components:
schemas:
ThingCollection:
type: object
required:
- things << array property is now required
properties:
things:
type: array
items:
$ref: '#/components/schemas/Thing'
|
</table>
### ibm-required-enum-properties-in-response
| Rule id: |
ibm-required-enum-properties-in-response |
| Description: |
The IBM Cloud API Handbook
states that within a response body, an enumeration field MUST be required.
This validation rule checks each schema used within a response to make sure each enumeration property is defined as required
and not optional.
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/thing':
get:
operationId: list_things
responses:
200:
content:
'application/json':
schema:
$ref: '#/components/schemas/ThingCollection'
components:
schemas:
ThingCollection:
type: object
required:
- things
properties:
things:
type: array
items:
$ref: '#/components/schemas/Thing'
collection_status: << optional enumeration property
type: string
enum:
- preliminary
- final
- under_review
|
</tr>
| Compliant example: |
paths:
'/v1/thing':
get:
operationId: list_things
responses:
200:
content:
'application/json':
schema:
$ref: '#/components/schemas/ThingCollection'
components:
schemas:
ThingCollection:
type: object
required:
- things
- collection_status << enumeration property is now required
properties:
things:
type: array
items:
$ref: '#/components/schemas/Thing'
collection_status:
type: string
enum:
- preliminary
- final
- under_review
|
</table>
### ibm-resource-response-consistency
| Rule id: |
ibm-requestbody-name |
| Description: |
Synchronous responses for create-style POST or update (PUT/PATCH) operations on a given resource instance should return the canonical schema for the resource, which is the schema returned in the GET operation on the single-instance path (e.g. `/resources/{id}`). Synchronous responses for bulk replace (PUT) operations should return the collection schema, which is the schema returned in the GET operation on the collection path (e.g. `/resources`). |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/thing':
post:
operationId: create_thing
requestBody:
content:
'application/json':
schema:
$ref: '#/components/schemas/ThingPrototype'
responses:
201:
content:
'application/json':
schema:
$ref: '#/components/schemas/OtherThing' # should be a ref to 'Thing'
'/v1/thing/{id}':
get:
operationId: get_thing
responses:
200:
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing'
|
</tr>
| Compliant example: |
paths:
'/v1/thing':
post:
operationId: create_thing
requestBody:
content:
'application/json':
schema:
$ref: '#/components/schemas/ThingPrototype'
responses:
201:
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing'
'/v1/thing/{id}':
get:
operationId: get_thing
responses:
200:
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing'
|
</table>
### ibm-response-status-codes
| Rule id: |
ibm-response-status-codes |
| Description: |
This rule performs a few different checks on the status codes used in operation responses:
- The use of the
422 - Unprocessable Entity status code is discouraged. Use 400 - Bad Request instead.
- The use of the
302 - Found status code is discouraged. Use 303 - See Other or
307 - Temporary Redirect instead.
- The
101 - Switching Protocols status code should not be used if any success status codes (2xx) are also present.
- Each operation should include at least one success status code (2xx). An exception to this is when the
101 - Switching Protocols status code is used, which should be extremely rare (it's normally used with websockets).
- A
204 - No Content response should not include content.
- A non-204 success status code (e.g.
200 - OK, 201 - Created, etc.) should include content.
- A "create"-type operation must return either a
201 - Created
or a 202 - Accepted status code. The one exception is, it may return a 204 - No Content status code
if the corresponding GET request for the same resource also returns a 204 - No Content status code (which indicates
there is no body representation for the resource).
- A PUT operation must return either a
200 - OK, 201 - Created,
or 202 - Accepted status code.
- A PATCH operation must return either a
200 - OK
or a 202 - Accepted status code.
- Status codes
301, 302, 305, 307 should include a response body.
Note that for the purposes of this rule, an operation is considered to be a "create"-type operation if the
operationId starts with "create" or the operation is a POST request and there is another path
present in the API that is similar to the path of the "create" operation, but with a trailing path parameter reference.
For example, "process_things" would be considered a "create"-type operation:
paths:
'/v1/things':
post:
operationId: process_things
...
'/v1/things/{thing_id}':
get:
operationId: get_thing
but "handle_things" would not:
paths:
'/v1/things':
post:
operationId: handle_things
...
The difference being that with the "handle_things" operation, there is no corresponding path
with a trailing path parameter reference that would give us a hint that "handle_things" is a create-type operation.
</li>
- An operation that returns a
202 - Accepted status code should not return any other
success (2xx) status codes. This is because an operation should be unambiguous in terms of whether or not
it is a synchronous or asynchronous operation.
</ul>
References:
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
description: 'Create a Thing instance.'
responses:
'204':
description: 'should not have content'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
'101':
description: 'invalid use of status code 101'
'422':
description: 'should use status code 400 instead'
|
</tr>
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
description: 'Create a Thing instance.'
responses:
'201':
description: 'Successfully created a new Thing instance.'
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
'400':
description: 'Thing instance was invalid'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
|
</table>
### ibm-schema-casing-convention
| Rule id: |
ibm-schema-casing-convention |
| Description: |
Schema names (the keys in `components -> schemas`) should follow the "upper camel case" convention
as required by the IBM Cloud API Handbook. Note that acronyms are allowed to be capitalized.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Configuration: |
This rule can be configured to define the specific regular expression used to enforce a case convention for schema name values.
To configure the rule, set the functionOptions field within the rule definition to be an object
that is the appropriate configuration to be used by Spectral's pattern() function
[1]
to enforce the desired case convention for schema name values.
The default configuration object provided in the rule definition is:
{
match: '/^[A-Z]+[a-z0-9]+([A-Z]+[a-z0-9]*)*$/'
}
To enforce a different case convention for schema name values, you'll need to
replace this rule with a new rule within your
custom ruleset and modify the configuration such that the value of the match field
specifies the desired case convention.
For example, to disallow capitalized acronymns for schema names, the configuration object would look like this:
{
match: '/^[A-Z][a-z0-9]+([A-Z][a-z0-9]+)*$/'
}
</td>
</tr>
|
| Non-compliant example:</td>
|
components:
schemas:
specific_thing:
type: object
properties:
...
|
</tr>
| Compliant example: |
components:
schemas:
SpecificThing:
type: object
properties:
...
|
</table>
### ibm-schema-description
| Rule id: |
ibm-schema-description |
| Description: |
Each schema should include a description. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
type: object
properties:
...
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
description: >-
A Thing instance is used as a way to demonstrate how various
validation rules may be applied to an API definition.
type: object
properties:
...
|
</table>
### ibm-schema-keywords
| Rule id: |
ibm-schema-keywords |
| Description: |
This rule verifies that only certain keywords (fields) are used when defining schemas and schema properties
in an OpenAPI 3.1.x document. The allowable keywords are configurable (see the Configuration section below).
|
| Severity: |
error |
| OAS Versions: |
oas3_1 |
| Configuration: |
This rule supports a configuration object that specifies the set of keywords that are allowed within a schema
or schema property.
The default configuration object provided with the rule is:
{
keywordAllowList: [
'$ref',
'additionalProperties',
'allOf',
'anyOf',
'default',
'description',
'discriminator',
'enum',
'example',
'examples',
'exclusiveMaximum',
'exclusiveMinimum',
'format',
'items',
'maximum',
'maxItems',
'maxLength',
'maxProperties',
'minimum',
'minItems',
'minLength',
'minProperties',
'multipleOf',
'not',
'oneOf',
'pattern',
'patternProperties',
'properties',
'readOnly',
'required',
'title',
'type',
'uniqueItems',
'unevaluatedProperties',
'writeOnly',
]
}
To configure the rule with a different set of allowable keywords, you'll need to
replace this rule with a new rule within your
custom ruleset and modify the configuration such that the value of the keywordAllowList field
contains the desired set of keywords to be checked.
For example, to configure the rule so that uniqueItems and unevaluatedProperties are disallowed,
modify the configuration to remove these keywords from the keywordAllowList
configuration field, like this:
{
keywordAllowList: [
'$ref',
'additionalProperties',
'allOf',
'anyOf',
'default',
'description',
'discriminator',
'enum',
'example',
'examples',
'exclusiveMaximum',
'exclusiveMinimum',
'format',
'items',
'maximum',
'maxItems',
'maxLength',
'maxProperties',
'minimum',
'minItems',
'minLength',
'minProperties',
'multipleOf',
'not',
'oneOf',
'pattern',
'patternProperties',
'properties',
'readOnly',
'required',
'title',
'type',
'writeOnly',
]
}
</td>
</tr>
|
| Non-compliant example:</td>
|
components:
schemas:
Things:
type: object
properties:
thing_id:
type: string
$comment: A comment about this property definition
nullable: true
|
</tr>
| Compliant example: |
components:
schemas:
Things:
type: object
properties:
thing_id:
description: A comment about this property definition
type:
- string
- null
|
</table>
### ibm-schema-naming-convention
| Rule id: |
ibm-schema-naming-convention |
| Description: |
The name of each schema should follow the IBM Cloud API Handbook schema naming conventions.
The rule checks the names of collection schemas, resource collection element schemas, creation/replacement schemas, and patch schemas against the name of the associated canonical schema to ensure the names follow the guidelines.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
/v1/things:
post:
requestBody:
content:
'application/json':
schema:
$ref: '#/components/schemas/ThingCreator' # Should be ThingPrototype
/v1/things/{id}:
get:
responses:
200:
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing' # Canonical schema
|
</tr>
| Compliant example: |
paths:
/v1/things:
post:
requestBody:
content:
'application/json':
schema:
$ref: '#/components/schemas/ThingPrototype'
/v1/things/{id}:
get:
responses:
200:
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing'
|
</table>
### ibm-schema-type
| Rule id: |
ibm-schema-type |
| Description: |
Schemas and schema properties should have a non-empty type field.
This rule is disabled by default. Enable it in your Spectral config file to utilize this validation.
|
| Severity: |
off |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
description: An underspecified schema
...
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
type: string
description: An string schema
...
|
</table>
### ibm-schema-type-format
| Rule id: |
ibm-schema-type-format |
| Description: |
Schemas and schema properties must use a valid combination of the type and format fields
[1].
The following table defines the valid combinations:
| Type | Formats |
| string |
- binary
- byte
- crn
- date
- date-time
- email
- identifier
- password
- url
- uuid
|
| boolean | |
| integer | |
| number | |
| object | |
| array | |
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
type: bad_object
properties:
thing_url:
type: url
thing_crn:
type: crn
thing_cost:
type: float
thing_contents:
type: byte-array
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_url:
type: string
format: url
thing_crn:
type: string
format: crn
thing_cost:
type: number
format: float
thing_contents:
type: string
format: byte
|
</table>
### ibm-sdk-operations
| Rule id: |
ibm-sdk-operations |
| Description: |
This rule validates the structure of values specified for the x-sdk-operations
extension, using this JSON Schema document.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
n/a
|
</tr>
| Compliant example: |
n/a
|
</table>
### ibm-securityscheme-attributes
| Rule id: |
ibm-securityscheme-attributes |
| Description: |
Performs a series of validations on the content within security schemes to ensure they comply
with the constraints outlined in the OpenAPI Specification.
Specifically, the rule will perform these checks:
- Each security scheme must specify the
type property. Valid values for the type property are:
apiKey
http
oauth2
openIdConnect
- A security scheme with type
apiKey must specify the name and in properties.
Valid values for the in property are:
- A security scheme with type
http must specify the scheme property.
- A security scheme with type
oauth2 must specify the flows property.
Furthermore, the flows property must be an object that defines at least one of the following keys:
implicit
authorizationcode
clientCredentials
password
An implicit oauth2 flow must specify the scopes and authorizationUrl properties.
A password or clientCredentials oauth2 flow must specify the scopes and tokenUrl properties.
An authorizationCode oauth2 flow must specify the scopes, authorizationUrl, and tokenUrl properties.
- A security scheme with type
openIdConnect must specify the openIdConnectUrl property.
</td>
</tr>
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
securitySchemes:
BasicAuthScheme:
type: http
IAMAuthScheme:
type: apiKey
OAuth2Scheme:
type: oauth2
|
</tr>
| Compliant example: |
components:
securitySchemes:
BasicAuthScheme:
type: http
description: Basic authentication via the Authorization header
scheme: Basic
bearerFormat: bearer
IAMAuthScheme:
type: apiKey,
description: An IAM access token provided via the Authorization header
in: header
name: Authorization
OAuth2Scheme:
type: oauth2
description: Supported oauth2 authorizaton flows
flows:
implicit:
authorizationUrl: https://myoauthserver.com/auth
scopes:
writer: User can create resources
authorizationCode:
authorizationUrl: https://myoauthserver.com/auth
tokenUrl: https://myoauthserver.com/token
scopes:
reader: User can retrieve resources
|
</table>
### ibm-securityschemes
| Rule id: |
ibm-securityschemes |
| Description: |
Verifies the security schemes and security requirement objects.
Specifically, the rule will perform these checks:
- The name used within a security requirement object must correspond to a
security scheme that is properly defined in "components.securitySchemes".
- Each security scheme defined in "components.securitySchemes" should be referenced
by at least one security requirement object.
- Each scope referenced within a security requirement object for an oauth2-type security scheme
must be defined within that security scheme.
- Each scope that is defined within an oath2-type security scheme should be
referenced by at least one security requirement object.
- If a security requirement object is associated with a security scheme that does not support
scopes, then its scopes array MUST be empty.
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/things':
post:
operationId: create_thing
security:
- IAM: [] # refers to undefined security scheme "IAM"
components:
securitySchemes:
Basic:
type: http
scheme: basic
|
</tr>
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
security:
- IAM: []
components:
securitySchemes:
IAM:
in: header
name: Authorization
type: apiKey
|
</table>
### ibm-server-variable-default-value
| Rule id: |
ibm-server-variable-default-value |
| Description: |
Server variables should have a default value. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
servers:
- url: https://{region}.myservice.cloud.ibm.com
description: The region-based endpoints available for My Service.
variables:
region:
description: >-
The name of the region, which should be one of:
"global", "us-south", "us-east", "us-west", "us-north"
|
</tr>
| Compliant example: |
servers:
- url: https://{region}.myservice.cloud.ibm.com
description: The region-based endpoints available for My Service.
variables:
region:
default: global
description: >-
The name of the region, which should be one of:
"global", "us-south", "us-east", "us-west", "us-north"
|
</table>
### ibm-string-attributes
| Rule id: |
ibm-string-attributes |
| Description: |
This rule checks to make sure that string schema properties define the pattern, minLength and maxLength
fields in order to clearly define the set of valid values for the property.
[1].
Note that these checks are bypassed for the following scenarios:
- All checks are bypassed for string schemas that contain an
enum field.
- The check for the
pattern field is bypassed if format is set to
binary, byte, date, date-time, or url.
- The check for the
minLength field is bypassed if format is set to
date, identifier, or url.
- The check for the
maxLength field is bypassed if format is set to date.
This rule also checks non-string schema properties to make sure they do not define the
pattern, minLength and maxLength fields since these fields are applicable
only for string schemas.
</td>
</tr>
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
description: A Thing instance.
type: object
properties:
thing_id:
description: The unique identifier of the Thing instance.
type: string
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
description: A Thing instance.
type: object
properties:
thing_id:
description: The unique identifier of the Thing instance.
type: string
pattern: '^[a-zA-Z0-9]*$'
minLength: 8
maxLength: 64
example: 'ab38dd26z'
|
</table>
### ibm-success-response-example
| Rule id: |
ibm-success-response-example |
| Description: |
Response examples should be provided in the schema object - or as a sibling to the schema object -
within each response content field entry, in order to aid in the generation of API reference documentation.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
responses:
200:
content:
application/json:
schema:
type: string
|
</tr>
| Compliant example: |
The example may be provided in the schema object.
responses:
200:
content:
application/json:
schema:
type: string
example: 'example string'
Alternatively, the example may be provided as a sibling to the schema object.
responses:
200:
content:
application/json:
schema:
type: string
example: 'example string'
</td>
</tr>
</table>
### ibm-summary-sentence-style
| Rule id: |
ibm-summary-sentence-style |
| Description: |
An operation's summary field should contain a very brief description of the operation and should
not have a trailing period. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
/v1/things
get:
operationId: list_things
summary: List the Thing objects.
description: Retrieve a paginated collection of Thing instances.
|
</tr>
| Compliant example: |
paths:
/v1/things
get:
operationId: list_things
summary: List things
description: Retrieve a paginated collection of Thing instances.
|
</table>
### ibm-unevaluated-properties
| Rule id: |
ibm-unevaluated-properties |
| Description: |
This rule ensures that unevaluatedProperties is not enabled within a schema.
It checks to make sure that if the unevaluatedProperties field
is set on a schema, then it is set to the value false (i.e. disabled).
</tr>
|
| Severity: |
error |
| OAS Versions: |
oas3_1 |
| Non-compliant example:</td>
|
components:
schemas:
Thing:
type: object
properties:
id:
type: string
metadata:
description: additional info about the thing
type: object
unevaluatedProperties:
type: string
|
</tr>
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
id:
type: string
metadata:
description: additional info about the thing
type: object
unevaluatedProperties: false
|
</table>
### ibm-unique-parameter-request-property-names
| Rule id: |
ibm-unique-parameter-request-property-names |
| Description: |
The IBM Cloud API Handbook
discourages the use of path parameter names that match any of the names of
top-level properties in the operation's request body schema.
The primary justification for this guidance is that if the names of operation parameters collide with the names of top-level
request body properties, then it creates ambiguity and perhaps a lack of clarity for users of the API.
In fact, the guidance applies equally well for all parameter types, not just path parameters.
And more specifically, IBM's OpenAPI SDK Generator will "explode" an operation's request body under certain circumstances in order to
simplify the application code required to invoke the operation.
This means that, instead of representing the operation's request body as a single operation parameter, the generator
will expose each of the properties defined in the operation's request body
schema such that they appear to be individual operation parameters. This optimization makes it easier for
an SDK user to construct an instance of the request body schema (class, struct, etc.) when invoking the operation.
Because the request body schema properties are exposed as operation parameters, the generator must detect if there are
any name collisions between these schema properties and the operation's other parameters.
The generator will rename the request body schema properties if any collisions are detected,
but the names computed by the generator are not optimal from a usability standpoint, so it's better for the API
to be defined such that the name collisions are avoided altogether.
This validation rule checks each operation for name collisions between the operation's parameters and its request body
schema properties. An error is logged for each collision. Each of these errors should be addressed by renaming either
the parameter or request body schema property to avoid the collision.
</td>
</tr>
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
/v1/things:
parameters:
- in: query
name: thing_type
schema:
type: string
post:
operationId: create_thing
parameters:
- in: query
name: thing_size
schema:
type: integer
requestBody:
content:
application/json:
schema:
type: object
properties:
thing_type:
type: string
thing_size:
type: integer
created_at:
type: string
format: date-time
created_by:
type: string
format: email
|
</tr>
| Compliant example: |
To avoid the collisions, the schema properties `thing_type` and `thing_size` were renamed to `type` and `size` respectively.
We could have instead renamed the parameters in order to avoid the collisions.
paths:
/v1/things:
parameters:
- in: query
name: thing_type
schema:
type: string
post:
operationId: create_thing
parameters:
- in: query
name: thing_size
schema:
type: integer
requestBody:
content:
application/json:
schema:
type: object
properties:
type:
type: string
size:
type: integer
created_at:
type: string
format: date-time
created_by:
type: string
format: email
|
</table>
### ibm-use-date-based-format
| Rule id: |
ibm-use-date-based-format |
| Description: |
Schemas or properties that are date-based (i.e. the values they model
are dates or times) must be strings with a format of "date" or "date-time".
This rule validates that is the case for relevant schemas, which are determined
heuristically using the property name, in the case of schema properties, or
the example value provided for a schema or property.
|
| Severity: |
warning |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
Resource
type: object
properties:
created_at: # Name indicates it should be a date or date-time
type: integer
stamp: # Example value indicates it should be a date-time
type: string
example: '1990-12-31T23:59:60Z'
...
|
</tr>
| Compliant example: |
Resource
type: object
properties:
created_at:
type: string
format: date-time
stamp:
type: string
format: date-time
example: '1990-12-31T23:59:60Z'
...
|
</table>
### ibm-valid-path-segments
| Rule id: |
ibm-valid-path-segments |
| Description: |
This rule validates the path segments within each path string found in the API.
Specifically, the rule makes sure that any path segment containing a path parameter reference contains
only that parameter reference and nothing more.
For example, the path /v1/foos/_{foo_id}_ is invalid and should probably be /v1/foos/{foo_id}.
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
paths:
'/v1/foos/_{foo_id}_':
parameters:
- $ref: '#/components/parameters/FooIdParam'
get:
operationId: get_foo
...
|
</tr>
| Compliant example: |
paths:
'/v1/foos/{foo_id}':
parameters:
- $ref: '#/components/parameters/FooIdParam'
get:
operationId: get_foo
...
|
</table>
### ibm-valid-schema-example
| Rule id: |
ibm-valid-schema-example |
| Description: |
This rule validates each unique schema and ensures that any example(s) defined
is a valid instance of that schema. Note that this rule is an alternative to `oas3-valid-schema-example` and exists because that rule uses heuristics to find schemas that result in false positives. Also note that this rule is not an alternative to `oas3-valid-media-example` (it does not look for examples outside of a schema) which is not as susceptible to false positives.
|
| Severity: |
warning |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
Foo:
type: string
example: 42
|
</tr>
| Compliant example: |
components:
schemas:
Foo:
type: string
example: 'value'
|
</table>
### ibm-well-defined-dictionaries
| Rule id: |
ibm-well-defined-dictionaries |
| Description: |
This rule validates that any dictionary schemas are well defined and that all values share a single type.
Dictionaries are defined as object type schemas that have variable key names. They are distinct from model types,
which are objects with pre-defined properties. A schema must not define both concrete properties and variable key names.
Practically, this means a schema must explicitly define a `properties` object or an `(additional|pattern)Properties` schema, but not both.
If used, the `(additional|pattern)Properties` schema must define a concrete type. The concrete type of the values must not be a dictionary itself. See the IBM Cloud API Handbook documentation on types for more info.
|
| Severity: |
warning |
| OAS Versions: |
oas3 |
| Non-compliant example:</td>
|
components:
schemas:
AmbiguousDictionary:
type: object
additionalProperties: true # No type description of the values in the dictionary
ProblematicHybird:
type: object
properties:
name:
type: string
additionalProperties: # If the schema is a model, all property names/types should be explicit
type: integer
|
</tr>
| Compliant example: |
components:
schemas:
DefinedDictionary:
type: object
additionalProperties:
type: string # Map of string to type string
minLength: 1
maxLength: 42
DefinedModel:
type: object
properties:
name:
type: string
|
</table>
| | | |