This document outlines how to configure and use the IBM Cloud Validation Ruleset,
which is delivered in the @ibm-cloud/openapi-ruleset NPM package.
The IBM Cloud Validation Ruleset consists of:
- 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.
This table provides an overview of the IBM Cloud validation rules. More detailed information for each rule
is provided in the Reference section below.
| Rule Id | Severity | Description | OpenAPI Versions |
| ibm-accept-and-return-models |
error |
Request and response bodies must be defined as model instances. |
oas3 |
| ibm-anchored-patterns |
warn |
Schema "pattern" attributes should contain regular expressions that include start-of-line and end-of-line anchors (i.e. ^ and $ characters). |
oas3 |
| ibm-api-symmetry |
warn |
Schemas should follow the API Handbook guidance on symmetrical structure between requests and responses. |
oas3 |
| ibm-array-attributes |
warn |
Array schemas must define the items field, and should define the minItems and maxItems fields. |
oas3 |
| ibm-avoid-inline-schemas |
warn |
Inline object schemas should be avoided within requestBody schemas, response schemas, and schema properties.
Instead, use a ref to a named schema.
|
oas3 |
| ibm-avoid-multiple-types |
warn |
Multiple types within a schema's type field should be avoided because it creates ambiguity.
|
oas3_1 |
| ibm-avoid-property-name-collision |
error |
Avoid duplicate property names within a schema, even if they differ by case convention. |
oas3 |
| ibm-avoid-repeating-path-parameters |
warn |
Common path parameters should be defined on the path object instead of on each operation. |
oas3 |
| ibm-binary-schemas |
warn |
Makes sure that binary schemas are used only in proper locations within the API definition |
oas3 |
| ibm-collection-array-property |
warn |
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.
|
oas3 |
| ibm-content-contains-schema |
warn |
Content entries must specify a schema. |
oas3 |
| ibm-content-type-is-specific |
warn |
*/* should only be used when all content types are supported. |
oas3 |
| ibm-define-required-properties |
error |
If a schema's required field contains the name of a property, then that
property should defined within the schema. |
oas3 |
| ibm-discriminator-property |
error |
The discriminator property must be defined in the schema. |
oas3 |
| ibm-dont-require-merge-patch-properties |
warn |
JSON merge-patch requestBody schemas should have no required properties. |
oas3 |
| ibm-enum-casing-convention |
error |
Enum values should follow a specific case convention. |
oas3 |
| ibm-error-content-type-is-json |
warn |
Error responses should support application/json. |
oas3 |
| ibm-error-response-schemas |
warn |
Error response schemas should comply with API Handbook guidance. |
oas3 |
| ibm-etag-header |
error |
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. |
oas3 |
| ibm-integer-attributes |
error |
Integer schema properties should define the minimum and maximum fields. |
oas3 |
| ibm-major-version-in-path |
warn |
All paths must contain the API major version as a distinct path segment. |
oas3 |
| ibm-no-accept-header |
warn |
Operations should not explicitly define the Accept header parameter. |
oas3 |
| ibm-no-ambiguous-paths |
warn |
Checks for the presence of ambiguous path strings. |
oas3 |
| ibm-no-array-of-arrays |
warn |
Array schemas with items of type array should be avoided. |
oas3 |
| ibm-no-array-responses |
error |
Operations should avoid defining an array as the top-level structure of a response. |
oas3 |
| ibm-no-authorization-header |
warn |
Operations should not explicitly define the Authorization header parameter. |
oas3 |
| ibm-no-body-for-delete |
warn |
[Deprecated] DELETE operations should not contain a requestBody. This rule has been deprecated; please use
the ibm-no-operation-requestbody rule instead.
|
oas3 |
| ibm-no-circular-refs |
warn |
Makes sure that the API definition doesn't contain any circular references. |
oas3 |
| ibm-no-consecutive-path-parameter-segments |
error |
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. |
oas3 |
| ibm-no-content-type-header |
warn |
Operations should not explicitly define the Content-Type header parameter. |
oas3 |
| ibm-no-crn-path-parameters |
warn |
Verifies that path parameters are not defined as CRN (Cloud Resource Name) values. |
oas3 |
| ibm-no-default-for-required-parameter |
warn |
Required parameters should not define a default value. |
oas3 |
| ibm-no-duplicate-description-with-ref-sibling |
warn |
Ensures that the "ref-sibling" allOf pattern is not used unnecessarily to define a duplicate description. |
oas3 |
| ibm-no-if-modified-since-header |
warn |
Operations should avoid supporting the If-Modified-Since header parameter. |
oas3 |
| ibm-no-if-unmodified-since-header |
warn |
Operations should avoid supporting the If-Unmodified-Since header parameter. |
oas3 |
| ibm-no-nullable-properties |
warn |
Ensures that nullable properties are defined only within JSON merge-patch requestBody schemas, per API Handbook guidance.
|
oas3 |
| ibm-no-operation-requestbody |
warn |
Ensures that DELETE, GET, HEAD, and OPTIONS operations do not define a requestBody. |
oas3 |
| ibm-no-optional-properties-in-required-body |
off |
If a requestBody schema contains properties that are defined as required, then the requestBody itself
should probably be required instead of optional.
This rule is deprecated. Please use the ibm-no-required-properties-in-optional-body rule instead.
|
oas3 |
| ibm-no-ref-in-example |
info |
Makes sure that $ref is not used within an example field. |
oas3 |
| ibm-no-required-properties-in-optional-body |
info |
If a requestBody schema contains properties that are defined as required, then the requestBody itself
should probably be required instead of optional. |
oas3 |
| ibm-no-space-in-example-name |
warn |
The name of an entry in an examples field should not contain a space. |
oas3 |
| ibm-no-superfluous-allof |
warn |
Warns about schemas that contain only a single-element allOf, which are unnecessary./td>
| oas3 |
| ibm-no-unsupported-keywords |
error |
Checks for the use of unsupported keywords within an OpenAPI 3.1.x document. |
oas3_1 |
| ibm-openapi-tags-used |
warn |
Verifies that each defined tag is referenced by at least one operation. |
oas3 |
| ibm-operation-summary |
warn |
Each operation should have a non-empty summary. |
oas3 |
| ibm-operation-summary-length |
error |
The value of an operation summary must be 80 characters or less in length. |
oas3 |
| ibm-operation-responses |
error |
Verifies that each operation has a responses field. |
oas3_1 |
| ibm-operationid-casing-convention |
warn |
Operation ids should follow a specific case convention. |
oas3 |
| ibm-operationid-naming-convention |
warn |
Operation ids should follow a naming convention. |
oas3 |
| ibm-pagination-style |
warn |
Paginated list operations should comply with the API Handbook's pagination guidance. |
oas3 |
| ibm-parameter-casing-convention |
error |
Parameter names should follow a specific case convention. |
oas3 |
| ibm-parameter-description |
warn |
Parameters should have a non-empty description. |
oas3 |
| ibm-parameter-order |
warn |
All required operation parameters should be listed before optional parameters. |
oas3 |
| ibm-parameter-schema-or-content |
error |
Parameters must provide either a schema or content. |
oas3 |
| ibm-patch-request-content-type |
error |
Verifies that PATCH operations support only requestBody content types application/json-patch+json
or application/merge-patch+json. |
oas3 |
| ibm-path-segment-casing-convention |
error |
Path segments must follow a specific case convention. |
oas3 |
| ibm-pattern-properties |
error |
Enforces certain restrictions on the use of patternProperties within a schema. |
oas3_1 |
| ibm-precondition-headers |
error |
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 |
oas3 |
| ibm-prefer-token-pagination |
warn |
Paginated list operations should use token-based pagination, rather than offset/limit pagination |
oas3 |
| ibm-property-attributes |
error |
Performs a series of checks on the attributes defined for various schema types. |
oas3 |
| ibm-property-casing-convention |
error |
Schema property names should follow a specific case convention. |
oas3 |
| ibm-property-consistent-name-and-type |
off |
Schema properties that share the same name should also share the same type. This rule is disabled by default. |
oas3 |
| ibm-property-description |
warn |
Schema properties should have a non-empty description. |
oas3 |
| ibm-redirect-response-body |
error |
Performs multiple checks on the operation redirect response bodies based on status codes. |
oas3 |
| ibm-ref-pattern |
warn |
Ensures that $ref values follow the correct patterns. |
oas3 |
| ibm-request-and-response-content |
warn |
Request bodies and non-204 responses should define a content field. |
oas3 |
| ibm-requestbody-is-object |
warn |
A non-form request body should be defined as an object. |
oas3 |
| ibm-requestbody-name |
off |
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. |
oas3 |
| ibm-required-array-properties-in-response |
error |
Array properties defined in a response should be required, per API Handbook guidance.
|
oas3 |
| ibm-required-enum-properties-in-response |
error |
Enumeration properties defined in a response must be required, per API Handbook guidance.
|
oas3 |
| ibm-resource-response-consistency |
warn |
Operations that create or update a resource should return the same schema as the "GET" request for the resource. |
oas3 |
| ibm-response-status-codes |
warn |
Performs multiple checks on the status codes used in operation responses. |
oas3 |
| ibm-schema-casing-convention |
warm |
Schema names should follow a specific case convention. |
oas3 |
| ibm-schema-description |
warn |
Schemas should have a non-empty description. |
oas3 |
| ibm-schema-keywords |
error |
Verifies that schemas and schema properties in an OpenAPI 3.1 document are defined using only
specific "allow-listed" keywords. |
oas3_1 |
| ibm-schema-naming-convention |
warn |
Schemas should follow the API Handbook naming conventions. |
oas3 |
| ibm-schema-type |
off |
Schemas and schema properties should have a non-empty type field. This rule is disabled by default. |
oas3 |
| ibm-schema-type-format |
error |
Schemas and schema properties must use a valid combination of type and format. |
oas3 |
| ibm-sdk-operations |
warn |
Validates the structure of each x-sdk-operations object. |
oas3 |
| ibm-securityscheme-attributes |
warn |
Performs a series of validations on the content within security schemes. |
oas3 |
| ibm-securityschemes |
warn |
Verifies the security schemes and security requirement objects. |
oas3 |
| ibm-server-variable-default-value |
warn |
Server variables should have a default value. |
oas3 |
| ibm-string-attributes |
warn |
String schema properties should define the pattern, minLength and maxLength fields. |
oas3 |
| ibm-success-response-example |
warn |
Each "success" response should provide an example. |
oas3 |
| ibm-summary-sentence-style |
warn |
An operation's summary field should not have a trailing period. |
oas3 |
| ibm-unevaluated-properties |
error |
Ensures that unevaluatedProperties is not enabled within a schema. |
oas3_1 |
| ibm-unique-parameter-request-property-names |
error |
Checks each operation for name collisions between the operation's parameters and its request body schema properties. |
oas3 |
| ibm-use-date-based-format |
warning |
Checks each schema and heuristically determines if it should be a string schema that uses a format of "date" or "date-time". |
oas3 |
| ibm-valid-path-segments |
error |
Checks each path string in the API to make sure path parameter references are valid within path segments. |
oas3 |
| ibm-valid-schema-example |
warning |
Checks each individual schema example to ensure compliance with the schema. |
oas3 |
| ibm-well-defined-dictionaries |
warn |
Dictionaries must be well defined and all values must share a single type. |
oas3 |
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:
'operation-operationId-unique': true,
'operation-parameters': true,
'operation-tag-defined': true,
'info-description': 'off',
'no-script-tags-in-markdown': true,
'openapi-tags': true,
'operation-description': true,
'operation-operationId': true,
'operation-tags': true,
'path-params': true,
'path-declarations-must-exist': true,
'path-keys-no-trailing-slash': true,
'path-not-include-query': true,
'no-$ref-siblings': true,
'typed-enum': true,
'oas2-operation-formData-consume-check': true,
'oas2-api-host': true,
'oas2-api-schemes': true,
'oas2-host-trailing-slash': true,
'oas2-valid-schema-example': 'warn',
'oas2-anyOf': true,
'oas2-oneOf': true,
'oas2-unused-definition': true,
'oas3-api-servers': true,
'oas3-examples-value-or-externalValue': true,
'oas3-server-trailing-slash': true,
'oas3-valid-media-example': 'warn',
'oas3-valid-schema-example': 'warn',
'oas3-schema': true,
'oas3-unused-component': true
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:
lint-openapi --ruleset /User/myuser/rules/my-rules.yaml my-service-api.yaml
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
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:
extends: '@ibm-cloud/openapi-ruleset'
rules:
info-contact: true
You could also set the severity of info-contact explicitly to error, warn, info, or hint.
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.
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.
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.
Here is our custom ruleset file (.spectral.js):
const ibmCloudValidationRules = require('@ibm-cloud/openapi-ruleset'); // Note 1
const { propertyCasingConvention } = require('@ibm-cloud/openapi-ruleset/src/functions');
const { schemas } = require('@ibm-cloud/openapi-ruleset-utilities/src/collections');
module.exports = {
extends: ibmCloudValidationRules,
rules: {
'ibm-property-casing-convention': { // Note 2
description: 'Property names must follow camel case',
message: '{{error}}',
resolved: true, // Note 3
given: schemas, // Note 4
severity: 'warn',
then: {
function: propertyCasingConvention, // Note 5
functionOptions: { // Note 6
type: 'camel'
}
}
}
}
};
Notes:
- 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.
To define a new rule as part of your custom ruleset, please read the Spectral Custom Rulesets documentation.
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.
This section provides reference documentation about the IBM Cloud Validation Rules contained
in the @ibm-cloud/openapi-ruleset package.
| 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
|
| 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.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
components:
schemas:
Thing:
type: object
properties:
id:
type: string
pattern: 'id-[0-9a-fA-F]+'
|
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
id:
type: string
pattern: '^id-[0-9a-fA-F]+$'
|
| Rule id: |
ibm-api-symmetry |
| Description: |
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, but may omit one or more properties 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.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
components:
schemas:
Thing:
type: object
properties:
id:
type: string
name:
type: string
age:
type: integer
ThingPrototype:
name:
type: string
age:
type: integer
color: # Does not exist on the resource!
type: string
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'
|
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
id:
type: string
name:
type: string
age:
type: integer
ThingPrototype: # A proper subset of properties
name:
type: string
age:
type: integer
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'
|
| Rule id: |
ibm-array-attributes |
| Description: |
Array schemas must define the items field, and should define the minItems and maxItems fields. Non-arrays must not define array keywords.
[1]. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
components:
schemas:
Array:
description: An Array instance.
type: array
|
| Compliant example: |
components:
schemas:
Array:
description: An Array instance.
type: array
minItems: 0
maxItems: 16
items:
type: string
pattern: '^[a-zA-Z0-9]*$'
minLength: 0
maxLength: 50
|
| Rule id: |
ibm-avoid-inline-schemas |
| Description: |
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.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
components:
schemas:
Thing:
type: object
properties:
id:
type: string
version:
type: object
properties:
major:
type: string
minor:
type: string
paths:
/v1/things:
post:
operationId: create_thing
description: Create a new Thing instance.
requestBody:
content:
application/json:
schema:
type: object
description: A Thing instance.
properties:
id:
type: string
version:
type: object
properties:
major:
type: string
minor:
type: string
responses:
'200':
content:
application/json:
schema:
type: object
description: A Thing instance.
properties:
id:
type: string
version:
type: object
properties:
major:
type: string
minor:
type: string
|
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
id:
type: string
version:
$ref: '#/components/schemas/ThingVersion'
ThingVersion:
type: object
properties:
major:
type: string
minor:
type: string
paths:
/v1/things:
post:
operationId: create_thing
description: Create a new Thing instance.
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
|
| Rule id: |
ibm-avoid-multiple-types |
| Description: |
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
|
| 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). |
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
thing_type:
type: string
thingType:
type: string
|
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
thing_type:
type: string
|
| Rule id: |
ibm-avoid-repeating-path-parameters |
| Description: |
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
|
| 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.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
paths:
'/v1/logfile':
get:
operationId: download_logfile
responses:
'200':
description: 'Download confirmed!'
content:
application/json:
schema:
type: string
format: binary
|
| Compliant example: |
paths:
'/v1/logfile':
get:
operationId: download_logfile
responses:
'200':
description: 'Download confirmed!'
content:
application/octet-stream:
schema:
type: string
format: binary
|
| Rule id: |
ibm-collection-array-property |
| 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}").
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
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'
|
| 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'
|
| 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: |
responses:
200:
description: 'Success response!'
content:
application/json:
# schema not provided
|
| Compliant example: |
responses:
200:
description: 'Success response!'
content:
application/json:
schema:
type: string
|
| 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.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
requestBody:
content:
'*/*':
...
|
| Compliant example: |
requestBody:
content:
'application/json':
...
'text/plain':
...
|
| 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: |
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
required:
- thing_id
- thing_version
|
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
thing_version:
type: string
required:
- thing_id
- thing_version
|
| 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: |
components:
schema:
Thing:
description: A Thing instance.
type: object
properties:
thing_id:
type: string
thing_version:
type: string
discriminator:
propertyName: thing_type
|
| 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
|
| 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.
|
| 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
|
| 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'
}
|
| Non-compliant example: |
components:
schemas:
ThingType:
type: string
enum:
- thingType1
- thingType2
|
| Compliant example: |
components:
schemas:
ThingType:
type: string
enum:
- thing_type_1
- thing_type_2
|
| 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: |
responses:
400:
content:
'application/octet-stream':
...
|
| Compliant example: |
responses:
400:
content:
'application/json':
...
|
| 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.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-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:
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
|
| 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
|
| 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!'
|
| 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
|
| 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: |
openapi: 3.0.1
info:
version: 1.0.0
...
paths:
/things:
...
|
| Compliant example: |
openapi: 3.0.1
info:
version: 1.0.0
...
paths:
/v1/things:
...
|
| 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'
|
| 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}')
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}
Each of the pairs of path strings above would be considered ambiguous.
|
| 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':
...
|
| 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: |
requestBody:
content:
application/json:
schema:
type: array
items:
type: array
items:
type: string
|
| Compliant example: |
requestBody:
content:
application/json:
schema:
type: array
items:
type: string
|
| 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.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
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"} ]
|
| 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"} ]}
|
| 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.
|
| 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'
|
| 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'
|
| 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.
|
| 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'
|
| 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
|
| 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: |
paths:
'/v1/foos/{foo_id}/{bar_id}':
parameters:
- $ref: '#/components/parameters/FooIdParam'
- $ref: '#/components/parameters/BarIdParam'
get:
operationId: get_foobar
...
|
| Compliant example: |
paths:
'/v1/foos/{foo_id}/bars/{bar_id}':
parameters:
- $ref: '#/components/parameters/FooIdParam'
- $ref: '#/components/parameters/BarIdParam'
get:
operationId: get_foobar
...
|
| 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: |
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'
|
| 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'
|
| 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.
|
| 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
|
| 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: |
components:
parameters:
SortOrderParam:
name: sort_order
description: The sort order.
in: query
required: true
schema:
type: string
enum:
- asc
- desc
default: asc
|
| Compliant example: |
components:
parameters:
SortOrderParam:
name: sort_order
description: The sort order.
in: query
required: true
schema:
type: string
enum:
- asc
- desc
|
| 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
|
| 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'
|
| 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.'
|
| 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.'
|
| 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'
|
| 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'
|
| 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']
}
|
| Non-compliant example: |
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'
|
| 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'
|
| 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: |
paths:
'/v1/things':
post:
operationId: create_thing
requestBody:
required: false
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing' # Assume "Thing" schema has required properties
|
| 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
|
| 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: |
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'
|
| 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: |
paths:
'/v1/things':
post:
operationId: create_thing
requestBody:
required: false
content:
'application/json':
schema:
$ref: '#/components/schemas/Thing' # Assume "Thing" schema has required properties
|
| 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
|
| 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: |
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:
...
|
| 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:
...
|
| 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: |
components:
schemas:
Thing:
properties:
foo_ref:
allOf:
- $ref: '#/components/schemas/Foo'
<
|
| Compliant example: |
components:
schemas:
Thing:
properties:
foo_ref:
$ref: '#/components/schemas/Foo'
|
| 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: |
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
|
| 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
|
| 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: |
paths:
'/v1/things':
post:
operationId: create_thing
|
| 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
|
| 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
|
| 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
|
| 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'
}
|
| Non-compliant example: |
paths:
'/v1/things':
post:
operationId: createThing
|
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
|
| 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.
|
| 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
}
|
| 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
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
|
| 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
|
| 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
|
| 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'
}
}
|
| Non-compliant example: |
components:
parameters:
SortOrderParam:
name: sortOrder << camel-case
description: The sort order.
in: query
required: false
schema:
type: string
enum:
- asc
- desc
default: asc
|
| 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
|
| Rule id: |
ibm-parameter-description |
| Description: |
Parameters should have a non-empty description. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
components:
parameters:
SortOrderParam:
name: sort_order
in: query
required: false
schema:
type: string
enum:
- asc
- desc
default: asc
|
| 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
|
| 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
|
| 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: |
parameters:
- name: param1
in: query
description: query param
|
| Compliant example: |
parameters:
- name: param1
in: query
description: query param
schema:
type: string
|
| 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.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
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!'
|
| 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!'
|
| 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'
}
|
| Non-compliant example: |
paths:
'/v1/someThings/{thing_id}':
|
| Compliant example: |
paths:
'/v1/some_things/{thing_id}':
|
| 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
|
| 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: |
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.'
|
| 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.'
|
| 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.'
|
| 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: |
components:
schemas:
Thing:
type: object
properties:
thing_size:
type: integer,
minimum: 5
maximum: 4
|
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_size:
type: integer,
minimum: 4
maximum: 5
|
| 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'
}
|
| Non-compliant example: |
components:
schemas:
Thing:
type: object
properties:
thingId:
type: string
thingType:
type: string
|
| Compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
thing_type:
type: string
|
| 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: |
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
|
| Rule id: |
ibm-property-description |
| Description: |
Schema properties should have a non-empty description. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
components:
schemas:
Thing:
type: object
properties:
thing_id:
type: string
thing_type:
type: string
|
| 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
|
| 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:
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Compliant example: |
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'
|
| Non-compliant example: |
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'
|
| 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
|
| 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: |
responses:
200:
description: 'Success response!'
|
| Compliant example: |
responses:
200:
content:
application/json:
schema:
$ref: '#/components/schemas/Thing'
|
| 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: |
requestBody:
content:
application/json:
schema:
type: string
|
| Compliant example: |
requestBody:
content:
application/json:
schema:
type: object
properties:
prop1:
type: string
|
| 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.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
paths:
'/v1/logs':
post:
operationId: upload_logfile
requestBody:
content:
'application/octet-stream':
schema:
type: string
format: binary
|
| 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
|
| 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: |
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'
|
| 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'
|
| 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: |
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
|
| 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
|
| 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: |
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'
|
| 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'
|
| 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.
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.
References:
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
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'
|
| 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]+)*$/'
}
|
| Non-compliant example: |
components:
schemas:
specific_thing:
type: object
properties:
...
|
| Compliant example: |
components:
schemas:
SpecificThing:
type: object
properties:
...
|
| Rule id: |
ibm-schema-description |
| Description: |
Each schema should include a description. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
components:
schemas:
Thing:
type: object
properties:
...
|
| 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:
...
|
| 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',
]
}
|
| Non-compliant example: |
components:
schemas:
Things:
type: object
properties:
thing_id:
type: string
$comment: A comment about this property definition
nullable: true
|
| Compliant example: |
components:
schemas:
Things:
type: object
properties:
thing_id:
description: A comment about this property definition
type:
- string
- null
|
| 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: |
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
|
| 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'
|
| 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: |
components:
schemas:
Thing:
description: An underspecified schema
...
|
| Compliant example: |
components:
schemas:
Thing:
type: string
description: An string schema
...
|
| 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: |
components:
schemas:
Thing:
type: bad_object
properties:
thing_url:
type: url
thing_crn:
type: crn
thing_cost:
type: float
thing_contents:
type: byte-array
|
| 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
|
| 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: |
n/a
|
| Compliant example: |
n/a
|
| 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.
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example: |
components:
securitySchemes:
BasicAuthScheme:
type: http
IAMAuthScheme:
type: apiKey
OAuth2Scheme:
type: oauth2
|
| 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
|
| 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.
|
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
security:
- IAM: [] # refers to undefined security scheme "IAM"
components:
securitySchemes:
Basic:
type: http
scheme: basic
|
| Compliant example: |
paths:
'/v1/things':
post:
operationId: create_thing
security:
- IAM: []
components:
securitySchemes:
IAM:
in: header
name: Authorization
type: apiKey
|
| Rule id: |
ibm-server-variable-default-value |
| Description: |
Server variables should have a default value. |
| Severity: |
warn |
| OAS Versions: |
oas3 |
| Non-compliant example: |
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"
|
| 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.
|
| 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'
|
| 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: |
responses:
200:
content:
application/json:
schema:
type: string
|
| 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'
|
| 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: |
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.
|
| 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
|
| 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.
|
| Severity: |
error |
| OAS Versions: |
oas3 |
| Non-compliant example: |
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
|
| 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
|
| 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: |
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'
...
|
| 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'
...
|
| 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: |
paths:
'/v1/foos/_{foo_id}_':
parameters:
- $ref: '#/components/parameters/FooIdParam'
get:
operationId: get_foo
...
|
| Compliant example: |
paths:
'/v1/foos/{foo_id}':
parameters:
- $ref: '#/components/parameters/FooIdParam'
get:
operationId: get_foo
...
|
| 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: |
components:
schemas:
Foo:
type: string
example: 42
|
| Compliant example: |
components:
schemas:
Foo:
type: string
example: 'value'
|
| 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: |
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
|