You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
IBM Cloud validation rules: a collection of rules that implement and enforce the best practices found
in the IBM Cloud API Handbook.
Spectral's “oas" ruleset:
the IBM Cloud Validation Ruleset extends the spectral:oas ruleset, so all of the rules contained in
that ruleset are also available to users of the @ibm-cloud/openapi-ruleset package as well.
Overview of IBM Cloud validation rules
This table provides an overview of the IBM Cloud validation rules. More detailed information for each rule
is provided in the Reference section below.
Makes sure that each "list"-type 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.
Verifies that the ETag response header is defined in the GET operation
for any resources (paths) that support the If-Match and/or If-None-Match header parameters.
[Deprecated] DELETE operations should not contain a requestBody. This rule has been deprecated; please use
the ibm-no-operation-requestbody rule instead.
Checks each path string in the API definition to detect the presence of two or more consecutive
path segments that contain a path parameter reference (e.g. /v1/foos/{foo_id}/{bar_id}),
which is not allowed.
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
An operation should specify a request body name (with the x-codegen-request-body-name extension) if its requestBody
has non-form content. This rule is disabled by default.
Dictionaries must be well defined and all values must share a single type.
oas3
Overview of spectral:oas rules
As mentioned above, the IBM Cloud Validation Ruleset (@ibm-cloud/openapi-ruleset) extends
the spectral:oas ruleset.
While all of the spectral:oas rules are included, only the following rules are enabled by default:
You can customize any of the rules contained in the @ibm-cloud/openapi-ruleset
(including the rules in the spectral:oas ruleset) by creating a custom ruleset.
For detailed information on creating your own ruleset and how to extend other rulesets, please read
the Spectral Rulesets documentation.
There are two different ways that you can supply your custom ruleset file to the IBM OpenAPI Validator:
Name your custom ruleset file with one of the names (.spectral.yaml, .spectral.yml, .spectral.json or .spectral.js)
and place it in the current directory where you will be running the validator.
Use an arbitrary filename for your custom ruleset file (e.g. /User/myuser/rules/my-rules.yaml) and use
the --ruleset command line option to specify the name when running the validator.
Example:
In this document, we'll focus on how to customize and extend the rules found in the IBM Cloud Validation Ruleset.
There are a few different ways in which you can customize and extend rules. The customization options available to you
will depend on the type of customization that you need to do. This is described in the following sections.
Note: If you extend the @ibm-cloud/openapi-ruleset package in your custom ruleset file,
you MUST install the npm package first, using a command like this:
npm install @ibm-cloud/openapi-ruleset
Modify a rule's severity
If you would simply like to modify a rule's severity or disable a rule altogether,
follow the instructions in this section.
Caution
Disabling certain rules may lead to false negatives for problems identified by other rules.
For example, if you disable the ibm-schema-type-format rule, other rules which detect problems
in schemas with specific combinations of type and format may fail to identify which schemas
they should apply to.
Any rule in the @ibm-cloud/openapi-ruleset package can be configured to trigger an error, warning, info,
or hint message in the validator output.
For example, to configure the schema-description rule to trigger an info message instead of a warning,
specify the following in your custom ruleset file (this example uses the yaml format):
extends: '@ibm-cloud/openapi-ruleset'rules:
schema-description: info
To completely disable a rule, use the severity of off.
For example, to disable the schema-description rule, specify the following in your custom ruleset file:
extends: '@ibm-cloud/openapi-ruleset'rules:
schema-description: off
Since the @ibm-cloud/openapi-ruleset package includes all the rules in spectral:oas, you can also enable rules from that
ruleset that are disabled by default.
For example, to enable the info-contact rule with its default severity (warning), specify the following in your custom ruleset file:
You could also set the severity of info-contact explicitly to error, warn, info, or hint.
Advanced rule customization
You can customize more than just a rule's severity. You can also customize a rule's configuration to select non-default
options, etc. Not all rules support a configuration, but some do (for details about which rules support a configuration object,
please see the Reference section below).
In order to customize the configuration of a rule, you will need to re-define the entire rule within your custom ruleset.
For these types of customizations, please follow the instructions in the Custom Rules section below.
Define custom rules
If you would like to modify the configuration of an existing rule or define your own new rule, you can define custom rules
within your own ruleset.
For reference information on how to define your own custom rules, please read the
Spectral custom rulesets documentation.
Replace a rule from @ibm-cloud/openapi-ruleset
In this section, we'll focus on the goal of defining a new custom rule that replaces the ibm-property-casing-convention rule
within the @ibm-cloud/openapi-ruleset package.
Specifically, we'll configure our custom rule to enforce camel case within schema property names rather than the default snake case.
In this scenario, we will re-define the ibm-property-casing-convention rule within our custom ruleset, but we will re-use the
propertyCasingConvention custom function within the @ibm-cloud/openapi-ruleset package that implements the logic of this rule.
For this reason, we must implement our custom ruleset using javascript instead of yaml.
This custom ruleset extends @ibm-cloud/openapi-ruleset and also references the propertyCasingConvention function and the
schemas JSONPath collection, so we need to import each of these with require statements. In addition, be sure to install
the @ibm-cloud/openapi-ruleset package: npm install @ibm-cloud/openapi-ruleset.
This custom rule is re-defining (overriding) the ibm-property-casing-convention rule from the @ibm-cloud/openapi-ruleset package
so we need to use the same rule id (ibm-property-casing-convention). Alternatively, we could have used a different rule id of our choosing,
but we would then need to separately disable the existing ibm-property-casing-convention rule so that we don't end up using both rules
which would result in the simultaneous enforcement of two competing case conventions.
The resolved=true setting means that the rule will be invoked on the resolved version of the API definition (i.e. each $ref
will be resolved by replacing it with the referenced entity).
The use of the schemas collection for the value of the given field is a convenient way to express that the rule should be invoked
on each location within the resolved API definition where a schema might appear.
Our custom rule uses the same function (propertyCasingConvention) that is used by the original ibm-property-casing-convention rule
within the @ibm-cloud/openapi-ruleset package.
We set the functionOptions field to configure the rule to enforce camel case instead of the default snake case.
Define a new rule
To define a new rule as part of your custom ruleset, please read the Spectral Custom Rulesets documentation.
Spectral Overrides
Rather than turning off a Spectral rule entirely, Spectral overrides allow you to customize ruleset usage for different
files and projects without having to duplicate any rules.
For details on how to add overrides to your custom ruleset, please read the
Spectral overrides documentation.
Reference
This section provides reference documentation about the IBM Cloud Validation Rules contained
in the @ibm-cloud/openapi-ruleset package.
ibm-accept-and-return-models
Rule id:
ibm-accept-and-return-models
Description:
The IBM Cloud API Handbook model guidance states that "Every object returned or accepted by a service MUST be an instance of a model." A model is an object that defines concrete fields (and in this way, is distinct from a dictionary). This rule ensures that each JSON request and response body (accepted and returned objects, respectively) is a model instance by requiring that a schema defines concrete fields via the properties attribute.
Severity:
error
OAS Versions:
oas3
Non-compliant example:
requestBody:
content:
'application/json':
schema:
type: object
description: A dictionary-based request body, that should be a model
additionalProperties:
type: string
Compliant example:
requestBody:
content:
'application/json':
schema:
# Note that this should be defined through a "reference" to a
# named schema, using an inline schema for display purposes.
type: object
description: A model of a "Person" resource
properties:
name:
type: string
description: Name of the person
age:
type: integer
description: Age of the person, in years
ibm-anchored-patterns
Rule id:
ibm-anchored-patterns
Description:
The pattern attribute of a string schema provides a regular expression to validate string instances. This rule ensures that each pattern attribute contains an anchored regular expression. This implies that the regular expression starts with the ^ character and ends with the $ character.
This check is performed to ensure that string instances are validated in their entirety,
since an un-anchored regular expression might match on only part of the string instance.
Each resource-representing schema should follow the IBM Cloud API Handbook schema structure conventions. Specifically, this rule ensures that Summary, Prototype, and Patch schemas are proper graph fragments of the canonical schema they are variants of. According to the Handbook, "a graph fragment schema has the same structure as its canonical schema with some properties omitted from the schema or from any nested object schemas."
This convention ensures that resource-oriented APIs are symmetrical between requests and responses in how resources are represented.
Note: the rule will report additional details about each violation of the graph fragment pattern through "info" level logs. Pass the option --log-level ibm-api-symmetry=info to see more info about any violations that occur.
The use of inline object schemas within certain locations in your API definition are discouraged because
the SDK generator typically needs to refactor these inline schemas in order to correctly generate SDK code, and the schema names
computed by the SDK generator are unlikely to be optimal from a readability standpoint.
Specifically, this rule warns about the use of inline object schemas within request bodies, responses,
and nested schemas (e.g. a schema property, an array items schema, an additionalProperties schema, etc.).
More information about this can be found in the
API Handbook.
The OpenAPI 3.1 Specification allows multiple types to be used within a schema's type field, but this can create
ambiguity in an API definition. Therefore, multiple types should be avoided.
This rule will return an error for schemas that are defined with multiple types (e.g. ['string', 'integer', 'boolean']).
One exception to this is that the special type "null" is simply ignored by the rule when counting
the number of elements in the schema's type field. So, the type value ['string', 'integer']
would cause an error, but the type value ['string', 'null'] would not.
Severity:
error
OAS Versions:
oas3_1
Non-compliant example:
components:
schemas:
Thing:
type: object
properties:
id:
type: string
metadata:
description: additional info about the thing
type:
- string
- boolean
- integer
- null
Compliant example:
components:
schemas:
Thing:
type: object
properties:
id:
type: string
metadata:
description: additional info about the thing
type:
- string
- null
ibm-avoid-property-name-collision
Rule id:
ibm-avoid-property-name-collision
Description:
Property names within a schema must be unique, even if they differ by case convention
(e.g. properties thingType and thing_type defined within the same schema would violate this rule).
When defining a path parameter, it's a good practice to define it once in the path object's parameters field rather than
defining it separately within each of the operations that exist for that path.
This rule checks for situations in which a path parameter is defined identically within multiple operations under a given path,
and returns a warning to alert the user that the path parameter should be defined on the path object instead.
Severity:
warn
OAS Versions:
oas3
Non-compliant example:
paths:
'/v1/things/{thing_id}':
get:
operationId: get_thing
parameters:
- name: thing_id
in: path
description: The id of the thing instance.
schema:
type: string
delete:
operationId: delete_thing
parameters:
- name: thing_id
in: path
description: The id of the thing instance.
schema:
type: string
Compliant example:
paths:
'/v1/things/{thing_id}':
parameters:
- name: thing_id
in: path
description: The id of the thing instance.
schema:
type: string
get:
operationId: get_thing
delete:
operationId: delete_thing
ibm-binary-schemas
Rule id:
ibm-binary-schemas
Description:
This rule checks to make sure that binary schemas are used only in proper locations within the API definition.
Specifically, the rule will check to make sure a binary schema is NOT used in the following locations:
A schema associated with an operation parameter.
A schema associated with a requestBody with JSON content.
A schema associated with a response with JSON content.
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}").
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
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.
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.
Severity:
warn
OAS Versions:
oas3
Non-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:
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
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
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:
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.
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
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.
Severity:
error
OAS Versions:
oas3
Non-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'
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!'
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!'
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:
components:
schemas:
Thing:
description: A Thing instance.
type: object
properties:
thing_size:
description: The size of the Thing instance, in ml.
type: integer
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
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.
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.
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.
Severity:
warn
OAS Versions:
oas3
Non-compliant example:
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'
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.
Severity:
warn
OAS Versions:
oas3
Non-compliant example:
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'
Compliant example:
paths:
'/v1/things/{thing_id}':
parameters:
- $ref: '#/components/parameters/ThingIdParam'
delete:
operationId: delete_thing
responses:
'204':
description: 'The thing was deleted'
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:
components:
schemas:
Foo:
type: object
properties:
bar:
$ref: '#/components/schemas/Bar'
Bar:
type: object
properties:
foo:
$ref: '#/components/schemas/Foo'
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
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}.
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:
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'
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.
Severity:
warn
OAS Versions:
oas3
Non-compliant example:
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
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
ibm-no-default-for-required-parameter
Rule id:
ibm-no-default-for-required-parameter
Description:
Required parameters should not define a default value.
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
Severity:
warn
OAS Versions:
oas3
Non-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:
allOf:
- $ref: '#/components/schemas/PageLink'
- description: 'A link to a page of results'
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'
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.
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.'
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.
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.'
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:
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'
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:
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:
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.
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:
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'
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'
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.
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.
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:
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.
Compliant example:
openapi: 3.1.0
info:
title: Thing Service
description: A service that manages Things
version: 1.0.0
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:
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
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
ibm-operation-responses
Rule id:
ibm-operation-responses
Description:
This rule verifies that each operation has a responses field.
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
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:
paths:
'/v1/things':
post:
operationId: create_thing
description: Create a new Thing instance.
Compliant example:
paths:
'/v1/things':
get:
operationId: create_thing
description: Create a new Thing instance.
summary: Create a Thing
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:
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
Compliant example:
paths:
'/v1/things':
get:
operationId: create_thing
description: Create a new Thing instance.
summary: Create a Thing
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:
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.
Severity:
warn
OAS Versions:
oas3
Non-compliant example:
paths:
'/v1/things':
post:
operationId: manufacture_thing
description: Create a new Thing instance.
summary: Create a Thing
'/v1/things/{thing_id}':
get:
operationId: retrieve_thing
description: Get a Thing instance.
summary: Get a Thing
Compliant example:
paths:
'/v1/things':
post:
operationId: create_thing
description: Create a new Thing instance.
summary: Create a Thing
'/v1/things/{thing_id}':
get:
operationId: get_thing
description: Get a Thing instance.
summary: Get a Thing
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].
Severity:
warn
OAS Versions:
oas3
Non-compliant example:
n/a
Compliant example:
n/a
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:
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
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:
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
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
ibm-parameter-schema-or-content
Rule id:
ibm-parameter-schema-or-content
Description:
Each parameter must provide either a schema or content object.
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.
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'
}
Non-compliant example:
paths:
'/v1/someThings/{thing_id}':
Compliant example:
paths:
'/v1/some_things/{thing_id}':
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 $.
Severity:
error
OAS Versions:
oas3_1
Non-compliant example:
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
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
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.
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.'
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:
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.'
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.'
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.
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:
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:
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
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
ibm-property-description
Rule id:
ibm-property-description
Description:
Schema properties should have a non-empty description.
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
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.
Severity:
warn
OAS Versions:
oas3
Non-compliant example:
components:
schemas:
Foo:
type: object
properties:
bar:
$ref: '#/definitions/Bar'
definitions:
Bar:
type: object
properties:
bar:
type: string
Compliant example:
components:
schemas:
Foo:
type: object
properties:
bar:
$ref: '#/components/schemas/Bar'
Bar:
type: object
properties:
bar:
type: string
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.
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.
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.
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.
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:
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'
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.
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:
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.
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.
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'
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'
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:
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:
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:
...
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:
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:
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.
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:
n/a
Compliant example:
n/a
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:
cookie
header
query
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.
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"
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"
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
code>pattern, minLength and maxLength fields since these fields are applicable
only for string schemas.
Severity:
warn
OAS Versions:
oas3
Non-compliant example:
components:
schemas:
Thing:
description: A Thing instance.
type: object
properties:
thing_id:
description: The unique identifier of the Thing instance.
type: string
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'
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.
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:
paths:
/v1/things
get:
operationId: list_things
summary: List the Thing objects.
description: Retrieve a paginated collection of Thing instances.
Compliant example:
paths:
/v1/things
get:
operationId: list_things
summary: List things
description: Retrieve a paginated collection of Thing instances.
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).
Severity:
error
OAS Versions:
oas3_1
Non-compliant example:
components:
schemas:
Thing:
type: object
properties:
id:
type: string
metadata:
description: additional info about the thing
type: object
unevaluatedProperties:
type: string
Compliant example:
components:
schemas:
Thing:
type: object
properties:
id:
type: string
metadata:
description: additional info about the thing
type: object
unevaluatedProperties: false
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.
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.
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}.
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 `additionalProperties` schema, but not both.
If used, the `additionalProperties` 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:
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
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