Skip to content

Latest commit

 

History

History
6722 lines (6511 loc) · 177 KB

ibm-cloud-rules.md

File metadata and controls

6722 lines (6511 loc) · 177 KB

IBM Cloud Validation Ruleset

This document outlines how to configure and use the IBM Cloud Validation Ruleset, which is delivered in the @ibm-cloud/openapi-ruleset NPM package.

Table of contents

Ruleset Contents

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.

Overview of IBM Cloud validation rules

This table provides an overview of the IBM Cloud validation rules. More detailed information for each rule is provided in the Reference section below.

Rule IdSeverityDescriptionOpenAPI Versions
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-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 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-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-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 warn An operation should specify a request body name (with the x-codegen-request-body-name extension) if its requestBody has non-form content. 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-valid-path-segments error Checks each path string in the API to make sure path parameter references are valid within path segments. oas3
ibm-well-defined-dictionaries warn Dictionaries must be well defined and all values must share a single type. oas3

Overview of spectral:oas rules

As mentioned above, the IBM Cloud Validation Ruleset (@ibm-cloud/openapi-ruleset) extends the spectral:oas ruleset.
While all of the spectral:oas rules are included, only the following rules are enabled by default:

'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

Customization

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:

  1. 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.
  2. 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

Modify a rule's severity

If you would simply like to modify a rule's severity or disable a rule altogether, follow the instructions in this section.

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.

Advanced rule customization

You can customize more than just a rule's severity. You can also customize a rule's configuration to select non-default options, etc. Not all rules support a configuration, but some do (for details about which rules support a configuration object, please see the Reference section below).

In order to customize the configuration of a rule, you will need to re-define the entire rule within your custom ruleset. For these types of customizations, please follow the instructions in the Custom Rules section below.

Define custom rules

If you would like to modify the configuration of an existing rule or define your own new rule, you can define custom rules within your own ruleset.

For reference information on how to define your own custom rules, please read the Spectral custom rulesets documentation.

Replace a rule from @ibm-cloud/openapi-ruleset

In this section, we'll focus on the goal of defining a new custom rule that replaces the ibm-property-casing-convention rule within the @ibm-cloud/openapi-ruleset package. Specifically, we'll configure our custom rule to enforce camel case within schema property names rather than the default snake case.

In this scenario, we will re-define the ibm-property-casing-convention rule within our custom ruleset, but we will re-use the propertyCasingConvention custom function within the @ibm-cloud/openapi-ruleset package that implements the logic of this rule. For this reason, we must implement our custom ruleset using javascript instead of yaml.

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:

  1. 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.
  2. 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.
  3. 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).
  4. 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.
  5. 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.
  6. We set the functionOptions field to configure the rule to enforce camel case instead of the default snake case.

Define a new rule

To define a new rule as part of your custom ruleset, please read the Spectral Custom Rulesets documentation.

Spectral Overrides

Rather than turning off a Spectral rule entirely, Spectral overrides allow you to customize ruleset usage for different files and projects without having to duplicate any rules. For details on how to add overrides to your custom ruleset, please read the Spectral overrides documentation.

Reference

This section provides reference documentation about the IBM Cloud Validation Rules contained in the @ibm-cloud/openapi-ruleset package.

ibm-api-symmetry

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 with some properties omitted from the schema or from any nested object schemas."

This convention ensures that resource-oriented APIs are symmetrical between requests and responses in how resources are represented.

Note: the rule will report additional details about each violation of the graph fragment pattern through "info" level logs. Pass the option --log-level ibm-api-symmetry=info to see more info about any violations that occur.

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'

ibm-array-attributes

Rule id: ibm-array-attributes
Description: Array schemas must define the items field, and should define the minItems and maxItems fields. [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

ibm-avoid-inline-schemas

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'

ibm-avoid-multiple-types

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

ibm-avoid-property-name-collision

Rule id: ibm-avoid-property-name-collision
Description: Property names within a schema must be unique, even if they differ by case convention (e.g. properties thingType and thing_type defined within the same schema would violate this rule).
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

ibm-avoid-repeating-path-parameters

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

ibm-binary-schemas

Rule id: ibm-binary-schemas
Description: This rule checks to make sure that binary schemas are used only in proper locations within the API definition. Specifically, the rule will check to make sure a binary schema is NOT used in the following locations:
  • A schema associated with an operation parameter.
  • A schema associated with a requestBody with JSON content.
  • A schema associated with a response with JSON content.
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

ibm-collection-array-property

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:

  1. the operation's operationId starts with "list" (e.g. "list_things")
  2. 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'

ibm-content-contains-schema

Rule id: ibm-content-contains-schema
Description: Each request body and response content field should contain a schema.
Severity: warn
OAS Versions: oas3
Non-compliant example:
responses:
  200:
    description: 'Success response!'
    content:
      application/json:
        # schema not provided
Compliant example:
responses:
  200:
    description: 'Success response!'
    content:
      application/json:
        schema:
          type: string

ibm-content-type-is-specific

Rule id: ibm-content-type-is-specific
Description: The use of */* as a mimetype within a content field should be avoided unless the API actually supports all content types.

If the API in fact supports all content types, this warning should be ignored.

Severity: warn
OAS Versions: oas3
Non-compliant example:
requestBody:
  content:
    '*/*':
      ...
Compliant example:
requestBody:
  content:
    'application/json':
      ...
    'text/plain':
      ...

ibm-define-required-properties

Rule id: ibm-define-required-properties
Description: This rule verifies that for each property name included in a schema's required list, that property must be defined within the schema. The property could be defined in any of the following ways:
  1. within the schema's properties field
  2. within one or more of the schemas listed in the allOf field
  3. 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

ibm-discriminator-property

Rule id: ibm-discriminator-property
Description: This rule is used in conjunction with Spectral's oas3-schema rule to verify that a discriminator object (if present) is defined properly within a schema. This includes the following validations:
  1. The discriminator field must be an object.
  2. The discriminator object must have a field named propertyName that defines the name of the discriminator property.
  3. The propertyName field must be of type string.
  4. 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

ibm-dont-require-merge-patch-properties

Rule id: ibm-dont-require-merge-patch-properties
Description: In order to adhere to the "merge-patch" semantics, the requestBody schema for a patch operation with application/merge-patch+json requestBody content should not define any required properties or specify a non-zero value for the minProperties field.

This rule verifies that "merge-patch" operations adhere to this requirement.

Severity: warn
OAS Versions: oas3
Non-compliant example:
paths:
  /v1/things/{thing_id}:
    patch:
      operationId: update_thing
      requestBody:
        content:
          'application/merge-patch+json':
            schema:
              $ref: '#/components/schemas/ThingPatch'
components:
  schemas:
    ThingPatch:
      type: object
      required:
        - name
        - long_description
      properties:
        name:
          description: The name of the Thing
          type: string
        long_description:
          description: The long description of the Thing
Compliant example:
paths:
  /v1/things/{thing_id}:
    patch:
      operationId: update_thing
      requestBody:
        content:
          'application/merge-patch+json':
            schema:
              $ref: '#/components/schemas/ThingPatch'
components:
  schemas:
    ThingPatch:          <<< no longer defines any required properties
      type: object
      properties:
        name:
          description: The name of the Thing
          type: string
        long_description:
          description: The long description of the Thing

ibm-enum-casing-convention

Rule id: ibm-enum-casing-convention
Description: This rule verifies that enum fields specified for string-type schema properties contain values that follow a specific case convention, with the default being snake case.
Severity: error
OAS Versions: oas3
Configuration: This rule can be configured to enforce a specific case convention for enum values. To configure the rule, set the functionOptions field within the rule definition to be an object that is the appropriate configuration to be used by Spectral's casing() function [1] to enforce the desired case convention for enum values.

The default configuration object provided in the rule definition is:

{
  type: 'snake'
}

To enforce a different case convention for enum values, you'll need to replace this rule with a new rule within your custom ruleset and modify the configuration such that the value of the type field specifies the desired case convention. For example, to enforce camel case for enum values, the configuration object would look like this:

{
  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

ibm-error-content-type-is-json

Rule id: ibm-error-content-type-is-json
Description: An error response likely returns application/json content and this rule warns when application/json is not the content mimetype. This rule should be ignored when the API actually returns an error response that is not application/json.
Severity: warn
OAS Versions: oas3
Non-compliant example:
responses:
  400:
    content:
      'application/octet-stream':
        ...
Compliant example:
responses:
  400:
    content:
      'application/json':
        ...

ibm-error-response-schemas

Rule id: ibm-error-response-schemas
Description: This rule implements the guidance related to error response schemas found in the API Handbook.

Specifically, the following checks are performed against each schema associated with an error response:

  • The error response schema should form a valid error container model as described by the API Handbook.
  • The errors property must be an array whose items field is a schema that forms a valid error model as described in the API Handbook.
  • If present, the target property must contain a valid error target model as described in the API Handbook.
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

ibm-etag-header

Rule id: ibm-etag-header
Description: This rule checks each path item (the object containing operations with keys 'get', 'post', 'delete', etc.) to make sure that the path item's GET operation defines the ETag response header if it is, in fact, needed. An ETag response header is needed if there are operations within the same path item that support the If-Match or If-Not-Match header parameters.

The reasoning behind this rule is that if a given path has one or more operations in which the user needs to provide a value for the If-Match or If-None-Match header parameters (sometimes referred to as an "etag value"), then the API should provide a way for the user to obtain the etag value. And the standard way for a service to provide an etag value to the user is by returning it as the ETag response header within the GET operation's response.

Severity: error
OAS Versions: oas3
Non-compliant example:
paths:
  '/v1/things/{thing_id}':
    parameters:
      - name: thing_id
        description: The id of the Thing.
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: get_thing
      responses:
        '200':
          description: 'Success response!'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThingCollection'
    delete:
      operationId: delete_thing
      parameters:
        - name: 'If-Match'
          description: The etag value associated with the Thing instance to be deleted.
          in: header
          required: true
          schema:
            type: string
      responses:
        '204':
          description: 'Success response!'
Compliant example:
paths:
  '/v1/things/{thing_id}':
    parameters:
      - name: thing_id
        description: The id of the Thing.
        in: path
        required: true
        schema:
          type: string
    get:
      operationId: get_thing
      responses:
        '200':
          description: 'Success response!'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThingCollection'
          headers:
            ETag:
              description: The unique etag value associated with the instance that was retrieved.
              schema:
                type: string
    delete:
      operationId: delete_thing
      parameters:
        - name: 'If-Match'
          description: The etag value associated with the Thing instance to be deleted.
          in: header
          required: true
          schema:
            type: string
      responses:
        '204':
          description: 'Success response!'

ibm-major-version-in-path

Rule id: ibm-major-version-in-path
Description: Each path defined within the API definition should include a path segment for the API major version, of the form v<n>, and all paths should have the same API major version segment. The API major version can appear in either the server URL or in each path entry.
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:
    ...

ibm-no-accept-header

Rule id: ibm-no-accept-header
Description: Operations should not explicitly define the Accept header parameter. Instead, the value of the Accept parameter is inferred from the responses field.
Severity: warn
OAS Versions: oas3
Non-compliant example:
paths:
  '/v1/things':
    get:
      operationId: list_things
      parameters:
        - name: Accept
          in: header
          description: The expected content type within the response.
          schema:
            type: string
      responses:
        '200':
          description: 'Success response!'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThingCollection'
Compliant example:
paths:
  '/v1/things':
    get:
      operationId: list_things
      responses:
        '200':
          description: 'Success response!'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThingCollection'

ibm-no-ambiguous-paths

Rule id: ibm-no-ambiguous-paths
Description: The path strings defined within an OpenAPI document must be unique and unambiguous. In general, two paths are ambiguous if the following are true:
  • the two paths contain the same number of path segments (e.g. /v1/foo, /v1/{foo})
  • when comparing each of the respective path segments in each path string:
    1. both path segments are non-parameterized and are equal (e.g. 'foo' vs 'foo')
    2. one or the other of the path segments is parameterized (e.g. 'foo' vs '{foo_id}')
    3. 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':
    ...

ibm-no-array-of-arrays

Rule id: ibm-no-array-of-arrays
Description: Array schemas with items of type array should be avoided
Severity: warn
OAS Versions: oas3
Non-compliant example:
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

ibm-no-array-responses

Rule id: ibm-no-array-responses
Description: This rule checks to make sure that operations do not define an array as the top-level structure within a response. The recommendation is to instead use an object with a property that contains the array. This will allow you to expand the definition of the response body (e.g. add new properties) in a compatible way in the future if needed.
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"} ]}

ibm-no-authorization-header

Rule id: ibm-no-authorization-header
Description: Operations should not explicitly define the Authorization header parameter. Instead, the security object should be used to indicate the supported authentication mechanisms. The security object can be defined at an operation level (which would apply only to that operation) or at a global level within the API definition (which would apply to all operations).

Within generated SDKs, the Authorization header will be managed automatically by the built-in authenticator support.

Non-SDK users (those using curl, for example) can infer the use of the Authorization header from the security object in the API definition together with other documentation provided for the service.

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'

ibm-no-body-for-delete

Rule id: ibm-no-body-for-delete [Deprecated]
Description: This rule checks each DELETE operation and will return a warning if the operation contains a requestBody.

This rule has been deprecated and is now disabled in the IBM Cloud Validation Ruleset. Please use the ibm-no-operation-requestbody rule instead.

Severity: warn
OAS Versions: oas3
Non-compliant example:
paths:
  '/v1/things/{thing_id}':
    parameters:
      - $ref: '#/components/parameters/ThingIdParam'
    delete:
      operationId: delete_thing
      requestBody:
          description: 'The Thing instance to be deleted.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Thing'
      responses:
        '204':
          description: 'The thing was deleted'
Compliant example:
paths:
  '/v1/things/{thing_id}':
    parameters:
      - $ref: '#/components/parameters/ThingIdParam'
    delete:
      operationId: delete_thing
      responses:
        '204':
          description: 'The thing was deleted'

ibm-no-circular-refs

Rule id: ibm-no-circular-refs
Description: This rule checks to make sure that the API definition doesn't contain circular references. A circular reference (or cycle) would be a $ref to some sort of object (e.g. a schema) where traversing the referenced object's various sub-objects (e.g. schema properties, allOf/anyOf/oneOf lists, "additionalProperties", "items", etc.) leads us to a $ref that is a reference to the original referenced object. One example of a circular reference would be a schema "Foo" that contains a property "foo" that is an instance of "Foo" itself. Another example would be a "Foo" schema that contains property "bar" that is an instance of the "Bar" schema, and "Bar" contains a property "foo" that is an instance of the "Foo" schema. Any reference to either "Foo" or "Bar" will be a circular reference.
Severity: warn
OAS Versions: oas3
Non-compliant example:
components:
  schemas:
    Foo:
      type: object
      properties:
        bar:
          $ref: '#/components/schemas/Bar'
    Bar:
      type: object
      properties:
        foo:
          $ref: '#/components/schemas/Foo'
Compliant example:
components:
  schemas:
    Foo:
      type: object
      properties:
        bar:
          $ref: '#/components/schemas/Bar'
    Bar:
      type: object
      properties:
        foo_id:               # include only the Foo instance's id,
          type: string        # not the entire Foo instance

ibm-no-consecutive-path-parameter-segments

Rule id: ibm-no-consecutive-path-parameter-segments
Description: This rule checks each path string in the API to detect the presence of two or more path segments that contain a parameter reference, which is not allowed. For example, the path /v1/foos/{foo_id}/{bar_id} is invalid and should probably be /v1/foos/{foo_id}/bars/{bar_id}.
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
    ...

ibm-no-content-type-header

Rule id: ibm-no-content-type-header
Description: Operations should not explicitly define the Content-Type header parameter. Instead, the value of the Content-Type parameter is inferred from the requestBody field. Note that the Content-Type header parameter is managed automatically by generated SDKs.
Severity: warn
OAS Versions: oas3
Non-compliant example:
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'

ibm-no-crn-path-parameters

Rule id: ibm-no-crn-path-parameters
Description: This rule checks to make sure that there are no path parameters that are defined as a CRN (Cloud Resource Name) value.

In order to determine whether or not a path parameter is considered to be defined as a CRN value, this validation rule will perform the following checks:

  • The parameter's name field contains "crn" (e.g. "resource_crn")
  • The parameter's schema is defined with type=string, format=crn
  • The parameter's schema is defined with a pattern field that starts with either "crn" or "^crn" (e.g. 'crn:[-0-9A-Fa-f]+')
  • The parameter's example field contains a CRN-like value (e.g. "crn:0afd-0138-2636")
  • The parameter's examples field contains an entry containing a CRN-like value, as in this example:
    
    components:
      parameters:
        ThingIdParam:
          name: thing_id
          description: The id of the Thing instance
          in: path
          required: true
          schema:
            type: string
          examples:
            crn_example:
              value: 'crn:0afd-0138-2636'
    
  • The parameter schema's example field contains a CRN-like value (e.g. "crn:0afd-0138-2636")
  • The parameter's description field contains either "CRN" or "Cloud Resource Name"
  • The parameter schema's description field contains either "CRN" or "Cloud Resource Name"
These checks are logically OR'd together, so that if any one or more of these checks are true for a particular parameter, then a warning is raised for that parameter.
Severity: warn
OAS Versions: oas3
Non-compliant example:
components:
  parameters:
    ThingCrnParam:
      name: thing_crn
      description: The CRN associated with the Thing instance
      in: path
      required: true
      schema:
        type: string
        format: crn
        pattern: '^crn:[-0-9A-Fa-f]+$'
        minLength: 5
        maxLength: 32
Compliant example:
components:
  parameters:
    ThingIdParam:
      name: thing_id
      description: The id associated with the Thing instance
      in: path
      required: true
      schema:
        type: string
        format: identifier
        pattern: '^id:[-0-9A-Fa-f]+$'
        minLength: 5
        maxLength: 32

ibm-no-default-for-required-parameter

Rule id: ibm-no-default-for-required-parameter
Description: Required parameters should not define a default value.
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

ibm-no-duplicate-description-with-ref-sibling

Rule id: ibm-no-duplicate-description-with-ref-sibling
Description: This rule checks for instances where the "ref sibling" allOf pattern is used to override the description of a referenced schema, but yet the overridden description is the same as that defined inside the referenced schema.

Prior to OpenAPI 3.0, when defining a schema one could use a $ref along with additional attributes in order to reference a named schema and also override those attributes defined within the referenced schema. A common use of this pattern was to override a referenced schema's description with a more specific description. Here is an example (a swagger 2.0 fragment):

definitions:
  PageLink:
    description: 'A link to a page of results'        <<< general description
    type: object
    properties:
      href:
        description: 'The URL string pointing to a specific page of results'
        type: string
  ResourceCollection:
    description: 'A collection of resources returned by the list_resources operation'
    type: object
    properties:
      first:
        $ref: '#/definitions/PageLink'
        description: 'A link to the first page of results'     <<< more specific description
      next:
        $ref: '#/definitions/PageLink'
        description: 'A link to the next page of results'      <<< more specific description

In this example, the "first" and "next" properties are given specific descriptions that indicate they point to the first and next page of results, respectively.

Starting with OpenAPI 3.0, one can no longer use this pattern. If a schema definition contains the $ref attribute, then no other attributes are allowed to be defined alongsize it. So to work around this restriction, API authors typically use the "ref sibling" allOf pattern. The above example might look like this:

components:
  schemas:
    PageLink:
      description: 'A link to a page of results'        <<< general description
      type: object
      properties:
        href:
          description: 'The URL string pointing to a specific page of results'
          type: string
    ResourceCollection:
      description: 'A collection of resources returned by the list_resources operation'
      type: object
      properties:
        first:
          allOf:
            - $ref: '#/components/schemas/PageLink'
            - description: 'A link to the first page of results'     <<< more specific description
        next:
          description: 'A link to the next page of results'      <<< more specific description
          allOf:
            - $ref: '#/components/schemas/PageLink'
In this example the "first" property uses an allOf with two list elements, where the second list element schema overrides the description of the PageLink schema. The "next" property is defined using a variation of the "ref sibling" allOf pattern where the overridden description is defined directly as an attribute of the "next" schema itself rather than in the second allOf list element. Both are considered to be examples of the "ref sibling" allOf pattern.

This rule specifically looks for instances of this pattern where the overridden description is the same as the description defined within the referenced schema, thus making the use of the "ref sibling" pattern unnecessary. Here is an example of this:

components:
  schemas:
    PageLink:
      description: 'A link to a page of results'        <<< general description
      type: object
      properties:
        href:
          description: 'The URL string pointing to a specific page of results'
          type: string
    ResourceCollection:
      description: 'A collection of resources returned by the list_resources operation'
      type: object
      properties:
        page_link:
          allOf:
            - $ref: '#/components/schemas/PageLink'
            - description: 'A link to a page of results'     <<< duplicate description
Severity: warn
OAS Versions: oas3
Non-compliant example:
components:
  schemas:
    PageLink:
      description: 'A link to a page of results'
      type: object
      properties:
        href:
          description: 'The URL string pointing to a specific page of results'
          type: string
    ResourceCollection:
      description: 'A collection of resources returned by the list_resources operation'
      type: object
      properties:
        page_link:
          allOf:
            - $ref: '#/components/schemas/PageLink'
            - description: 'A link to a page of results'
Compliant example:
components:
  schemas:
    PageLink:
      description: 'A link to a page of results'
      type: object
      properties:
        href:
          description: 'The URL string pointing to a specific page of results'
          type: string
    ResourceCollection:
      description: 'A collection of resources returned by the list_resources operation'
      type: object
      properties:
        page_link:
          $ref: '#/components/schemas/PageLink'

ibm-no-if-modified-since-header

Rule id: ibm-no-if-modified-since-header
Description: The API Handbook recommends against the use of the If-Modified-Since and If-Unmodified-Since header parameters. Operations should support If-Match and If-None-Match headers instead.

This rule warns about operations that support the If-Modified-Since header parameter.

Severity: warn
OAS Versions: oas3
Non-compliant example:
paths:
  '/v1/things/{thing_id}':
    parameters:
      - $ref: '#components/parameters/ThingIdParam'
    get:
      operationId: get_thing
      parameters:
        - name: If-Modified-Since
          in: header
          description: |-
            The operation will succeed only if the resource has been last modified 
            after the date specified for this header parameter.
          schema:
            type: string
      responses:
        '200':
          description: 'Resource was retrieved successfully!'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Thing'
        '412':
          description: 'Resource has not been modified after If-Modified-Since date.'
Compliant example:
paths:
  '/v1/things/{thing_id}':
    parameters:
      - $ref: '#components/parameters/ThingIdParam'
    get:
      operationId: get_thing
      parameters:
        - name: If-None-Match
          in: header
          description: |-
            The operation will succeed only if the resource's current ETag value 
            does not match the value specified for this header parameter.
          schema:
            type: string
      responses:
        '200':
          description: 'Resource was retrieved successfully!'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Thing'
        '412':
          description: 'Resource current ETag matches If-None-Match value.'

ibm-no-if-unmodified-since-header

Rule id: ibm-no-if-unmodified-since-header
Description: The API Handbook recommends against the use of the If-Modified-Since and If-Unmodified-Since header parameters. Operations should support If-Match and If-None-Match headers instead.

This rule warns about operations that support the If-Unmodified-Since header parameter.

Severity: warn
OAS Versions: oas3
Non-compliant example:
paths:
  '/v1/things/{thing_id}':
    parameters:
      - $ref: '#components/parameters/ThingIdParam'
    delete:
      operationId: delete_thing
      parameters:
        - name: If-Unmodified-Since
          in: header
          description: |-
            The operation will succeed only if the resource has not been modified 
            after the date specified for this header parameter.
          schema:
            type: string
      responses:
        '204':
          description: 'Resource was deleted successfully!'
        '412':
          description: 'Resource was last modified after the If-Unmodified-Since date.'
Compliant example:
paths:
  '/v1/things/{thing_id}':
    parameters:
      - $ref: '#components/parameters/ThingIdParam'
    delete:
      operationId: delete_thing
      parameters:
        - name: If-Match
          in: header
           description: |-
            The operation will succeed only if the resource's current ETag value
            matches the value specified for this header parameter.
          schema:
            type: string
      responses:
        '204':
          description: 'Resource was deleted successfully!'
        '412':
          description: 'Resource current ETag value does not match the If-Match value.'

ibm-no-nullable-properties

Rule id: ibm-no-nullable-properties
Description: The API Handbook provides guidance related to the use of nullable schema properties. Specifically, the API Handbook allows nullable schema properties to be defined only within JSON merge-patch request body schemas. This rule ensures that nullable properties are not defined elsewhere.
Severity: warn
OAS Versions: oas3
Non-compliant example:
components:
  schemas:
    Thing:
      type: object
      properties:
        thing_id:
          type: string
        thing_name:
          type: string
        thing_size:
          type: integer
        thing_type:
          type: string
          nullable: true   <<< not valid in a response schema
    ThingPatch:
      type: object
      properties:
        thing_name:
          type: string
           nullable: true   <<< valid only in a merge-path requestBody schema
        thing_size:
          type: integer
          nullable: true   <<< valid only in a merge-path requestBody schema
        thing_type:
          type: string
          nullable: true   <<< valid only in a merge-path requestBody schema
paths:
  '/v1/things/{thing_id}':
    parameters:
      - $ref: '#/components/parameters/ThingIdParameter'
    patch:
      operationId: update_thing
      requestBody:
        description: An object used to modify an existing Thing instance
        content:
          application/merge-patch+json:
            schema:
              $ref: '#/components/schemas/ThingPatch'
      responses:
        '200':
          description: Thing instance was updated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Thing'
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'

ibm-no-operation-requestbody

Rule id: ibm-no-operation-requestbody
Description: The API Handbook provides guidance related to the use of various HTTP methods. In particular, the API Handbook discourages the use of a requestBody with DELETE, GET, HEAD and OPTIONS operations. This rule ensures that these operations do not define a requestBody.
Severity: warn
OAS Versions: oas3
Configuration: This rule supports a configuration that specifies the set of HTTP methods that are checked for a requestBody.

The default configuration object provided with the rule is:

{
  httpMethods: ['delete', 'get', 'head', 'options']
}

To configure the rule with a different set of HTTP methods, you'll need to replace this rule with a new rule within your custom ruleset and modify the configuration such that the value of the httpMethods field specifies the desired set of HTTP methods to be checked. For example, to enforce the rule for DELETE, HEAD and OPTIONS operations, the configuration object would look like this:

{
  httpMethods: ['delete', 'head', 'options']
}
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'

ibm-no-optional-properties-in-required-body

Rule id: ibm-no-optional-properties-in-required-body
Description: This rule scrutinizes optional request bodies because in most cases, they should be required. Specifically, this rule examines the schemas associated with optional request bodies and if there are required properties, then it is likely that the API author intended for the request body to be required.
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

ibm-no-space-in-example-name

Rule id: ibm-no-space-in-example-name
Description: The name of an entry in an examples field should not contain a space.
Severity: warn
OAS Versions: oas3
Non-compliant example:
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:
        ...

ibm-no-unsupported-keywords

Rule id: ibm-no-unsupported-keywords
Description: This rule checks for the presence of specific keywords within an OpenAPI 3.1.x document that are not yet supported by IBM's SDK-related tooling - specifically the jsonSchemaDialect and webhooks keywords. An error is logged if either of these keywords is found in the document.
Severity: error
OAS Versions: oas3_1
Non-compliant example:
openapi: 3.1.0
info:
  title: Thing Service
  description: A service that manages Things
  version: 1.0.0
jsonSchemaDialect: 'https://spec.openapis.org/oas/3.1/dialect/base'    <<< not supported
webhooks:                                                              <<< not supported
  newThingTypeAvailable:
    post:
      description: |-
        A callback-like operation to be implemented by the client so that it
        can be informed of a new type of Thing supported by the server.
      requestBody:
        description: 'A new type of Thing can now be created on the server.'
          content:
            application/json:
              schema:
                type: object,
                properties:
                  thing_type:
                    description: 'The new type value that can be used to create a Thing instance.'
                    type: string
      responses:
        '200':
          description: |-
            Return a 200 status code to the server to indicate that the new Thing type
            was received successfully by the client.
Compliant example:
openapi: 3.1.0
info:
  title: Thing Service
  description: A service that manages Things
  version: 1.0.0

ibm-openapi-tags-used

Rule id: ibm-openapi-tags-used
Description: This rule verifies that each tag (defined in the tags field) is referenced by one or more operations.
Severity: warn
OAS Versions: oas3
Non-compliant example:
tags:
  - name: Things
    description: Operations related to Things.
  - name: UnusedTag
    description: This tag is not used.

paths: '/v1/things': post: operationId: create_thing description: Create a new Thing instance. summary: Create a Thing tags: - Things

Compliant example:
tags:
  - name: Things
    description: Operations related to Things.

paths: '/v1/things': post: operationId: create_thing description: Create a new Thing instance. summary: Create a Thing tags: - Things

ibm-operation-responses

Rule id: ibm-operation-responses
Description: This rule verifies that each operation has a responses field.
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

ibm-operation-summary

Rule id: ibm-operation-summary
Description: This rule verifies that each operation has a non-empty summary.
Severity: warn
OAS Versions: oas3
Non-compliant example:
paths:
  '/v1/things':
    post:
      operationId: create_thing
      description: Create a new Thing instance.
Compliant example:
paths:
  '/v1/things':
    get:
      operationId: create_thing
      description: Create a new Thing instance.
      summary: Create a Thing

ibm-operation-summary-length

Rule id: ibm-operation-summary-length
Description: This rule verifies that each operation's summary is at most 80 characters in length, per guidance in the API Handbook.
Severity: error
OAS Versions: oas3
Non-compliant example:
paths:
  '/v1/things':
    post:
      operationId: create_thing
      description: Create a new Thing instance.
      summary: Create a shiny, brand new, hot-off-the-press instance of the standard Thing resource
Compliant example:
paths:
  '/v1/things':
    get:
      operationId: create_thing
      description: Create a new Thing instance.
      summary: Create a Thing

ibm-operationid-casing-convention

Rule id: ibm-operationid-casing-convention
Description: Operation ids should follow a specific case convention, with the default being snake case.
Severity: warn
OAS Versions: oas3
Configuration: This rule can be configured to enforce a specific case convention for operationId values. To configure the rule, set the functionOptions field within the rule definition to be an object that is the appropriate configuration to be used by Spectral's casing() function [1] to enforce the desired case convention for operationId values.

The default configuration object provided in the rule definition is:

{
  type: 'snake'
}

To enforce a different case convention for operationId values, you'll need to replace this rule with a new rule within your custom ruleset and modify the configuration such that the value of the type field specifies the desired case convention. For example, to enforce camel case for operation ids, the configuration object would look like this:

{
  type: 'camel'
}
Non-compliant example:
paths:
  '/v1/things':
    post:
      operationId: createThing
Compliant example:
paths:
  '/v1/things':
    post:
      operationId: create_thing

ibm-operationid-naming-convention

Rule id: ibm-operationid-naming-convention
Description: Operation ids should follow a naming convention using standard, predictable verbs. For example, create_thing would be preferred over manufacture_thing when deciding on an operationId for the POST /v1/things operation. Likewise, for the GET /v1/things/{thing_id} operation, we might prefer get_thing over retrieve_thing for the operationId.

This rule will analyze the operations, looking for operationId values that are not using the recommended verbs.

Severity: warn
OAS Versions: oas3
Non-compliant example:
paths:
  '/v1/things':
    post:
      operationId: manufacture_thing
      description: Create a new Thing instance.
      summary: Create a Thing
  '/v1/things/{thing_id}':
    get:
      operationId: retrieve_thing
      description: Get a Thing instance.
      summary: Get a Thing
Compliant example:
paths:
  '/v1/things':
    post:
      operationId: create_thing
      description: Create a new Thing instance.
      summary: Create a Thing
  '/v1/things/{thing_id}':
    get:
      operationId: get_thing
      description: Get a Thing instance.
      summary: Get a Thing

ibm-pagination-style

Rule id: ibm-pagination-style
Description: This rule verifies that list-type operations implement pagination correctly per the guidelines in the API Handbook.

An operation is recognized as a paginated list-type operation if all of the following are true:

  • The path doesn't end in a path segment that is a path parameter reference (e.g. /v1/things vs /v1/things/{thing_id}).
  • The operation is a get.
  • The operation's response schema is an object containing an array property.
  • The operation defines either the offset query parameter or a page-token type query parameter whose name is one of the following: start(preferred), token, cursor, page, or page_token.

If an operation is recognized as a paginated list-type operation, then the following checks are performed:

  • If the operation has a limit query parameter, then it must be of type integer, optional, and have default and maximum values defined for it [1, 2].
  • If the operation has an offset query parameter, then it must be of type integer and optional [3].
  • If the operation has an offset query parameter, then it must also have a limit query parameter [4]. This is because the presence of the offset parameter indicates that the offset/limit style pagination is being used.
  • If the operation has a page-token type query parameter, then it must be of type string and optional, and its name should be start [5].
  • If the operation has a limit query parameter, then the response body schema must contain a limit schema property that is of type integer and required [6, 7].
  • If the operation has an offset query parameter, then the response body schema must contain an offset schema property that is of type integer and required [8].
  • If the operation's response body schema contains a total_count property, then it must be of type integer and required [9, 10].
  • The operation's response body schema should contain properties named first, last, previous and next that provide links to the first, last, previous and next page of results, respectively. Each of these properties should be defined as an object with a property named href of type string which contains the appropriate request URL string to be used to obtain that page of results [11].
Severity: warn
OAS Versions: oas3
Non-compliant example: n/a
Compliant example: n/a

ibm-parameter-casing-convention

Rule id: ibm-parameter-casing-convention
Description: This rule verifies that each parameter name complies with the casing convention associated with that parameter's type. For example, the default casing convention for query parameters is snake-case (e.g. my_query_param), the default for path parameters is snake-case (e.g. my_path_param), and the default casing convention for header params is kebab-separated pascal-case with provision for capitalized abbreviations (e.g. IBM-CustomHeader-Name). These default casing conventions constitute the default configuration for the rule, although the rule's configuration can be modified to fit your needs (see below).
Severity: error
OAS Versions: oas3
Configuration: This rule can be configured to enforce specific case conventions for each parameter type. To configure the rule, set the functionOptions field within the rule definition to be an object with keys that represent the different parameter types to be checked for proper case conventions ('query', 'path', and 'header'). The value associated with each entry should be an object that is the appropriate configuration to be used by either Spectral's casing() function [1] or pattern() function [2] (for greater control over the case convention check) to enforce the desired case convention for that parameter type. Additionally, you can define custom messages in the form "{parameter-type}Message".

The default configuration object provided in the rule definition is:

{
  query: {
    type: 'snake',
    separator: {
      char: '.'
    }
  },
  path: {
    type: 'snake'
  },
  // Spectral casing convention types aren't robust enough to handle
  // the complexity of headers, so we define our own kebab/pascal case regex.
  header: {
    match: '/^[A-Z]+[a-z0-9]*-*([A-Z]+[a-z0-9]*-*)*$/',
  },
  headerMessage: 'Header parameter names must be kebab-separated pascal case',
}
This enforces:
  • Query parameter names to be snake-case, while also allowing "." within the name
  • Path parameter names to be snake-case
  • Header parameter names to be in http header canonical form, which amounts to pascal casing with a hyphen ("-") separating the words (e.g. X-My-Header).

To disable the case convention checks for a particular parameter type, simply remove the entry for that parameter type from the configuration object.

If you want to use a different configuration for this rule other than the default configuration mentioned above, you'll need to replace this rule with a new rule within your custom ruleset and modify the configuration appropriately for your needs. For example, to disable the case convention checks on header parameter names, while enforcing camel-case conventions on query and path parameter names, the configuration object would look like this:

{
  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

ibm-parameter-description

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

ibm-parameter-order

Rule id: ibm-parameter-order
Description: It is a good practice to list the parameters within an operation such that all required parameters are listed first, then any optional parameters.
Severity: warn
OAS Versions: oas3
Non-compliant example:
paths:
  '/v1/things':
    get:
      operationId: list_things
      description: List the set of Things.
      summary: List Things
      parameters:
        - name: offset
          required: false
          in: query
          schema:
            type: integer
        - name: limit
          required: false
          in: query
          schema:
            type: integer
        - name: filter
          required: true
          in: query
          schema:
            type: string
Compliant example:
paths:
  '/v1/things':
    get:
      operationId: list_things
      description: List the set of Things.
      summary: List Things
      parameters:
        - name: filter
          required: true
          in: query
          schema:
            type: string
        - name: offset
          required: false
          in: query
          schema:
            type: integer
        - name: limit
          required: false
          in: query
          schema:
            type: integer

ibm-parameter-schema-or-content

Rule id: ibm-parameter-schema-or-content
Description: Each parameter must provide either a schema or content object.
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

ibm-patch-request-content-type

Rule id: ibm-patch-request-content-type
Description: The API Handbook recommends that PATCH operations contain request bodies that support only content types application/json-patch+json and application/merge-patch+json.

This rule verifies that each PATCH operation complies with this recommendation.

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!'

ibm-path-segment-casing-convention

Rule id: ibm-path-segment-casing-convention
Description: Path segments must follow a specific case convention, with the default being snake case.
Severity: error
OAS Versions: oas3
Configuration: This rule's default configuration will enforce snake case for path segments, but the rule can be configured to enforce a different case convention if desired.

To enforce a different case convention for path segments, you'll need to replace this rule with a new rule within your custom ruleset and modify the configuration such that the value of the type field specifies the desired case convention. For example, to enforce camel case for path segments, the configuration object would look like this:

{
  type: 'camel'
}
Non-compliant example:
paths:
  '/v1/someThings/{thing_id}':
Compliant example:
paths:
  '/v1/some_things/{thing_id}':

ibm-pattern-properties

Rule id: ibm-pattern-properties
Description: This rule enforces certain restrictions related to the use of the patternProperties field within a schema:
  • The patternProperties field must be an object with exactly one entry.
  • The patternProperties and additionalProperties fields are mutually exclusive within a particular schema.
Severity: error
OAS Versions: oas3_1
Non-compliant example:
components:
  schemas:
    Thing:
      type: object
      properties:
        id:
          type: string
        metadata:
          description: additional info about the thing
          type: object
          patternProperties:
            '^foo.*$':
              type: string
            '^bar.*$':
              type: integer
Compliant example:
components:
  schemas:
    Thing:
      type: object
      properties:
        id:
          type: string
        metadata:
          description: additional info about the thing
          type: object
          patternProperties:
            '^(foo|bar).*$':
              type: string

ibm-precondition-headers

Rule id: ibm-precondition-headers
Description: Operations that return a 412 status code must support at least one of the following header parameters: If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since. For more details, please see the API Handbook section on Conditional headers.
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.'

ibm-prefer-token-pagination

Rule id: ibm-prefer-token-pagination
Description: As per the API Handbook guidance on pagination, paginated list operations should use token-based pagination, rather than offset/limit pagination, wherever feasible.
Severity: warn
OAS Versions: oas3
Non-compliant example:
paths:
  '/v1/things/':
    get:
      operationId: list_things
      parameters:
        - name: offset
          in: query
          description: 'The offset of the first item to return.'
          required: false
          schema:
            type: integer
            format: int32
            minimum: 0
        - name: limit
          in: query
          description: 'The number of items to return per page.'
          required: false
          schema:
            type: integer
            format: int32
            minimum: 0
            maximum: 100
            default: 10
      responses:
        '200':
          description: 'Resources retrieved successfully!'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThingCollection'
        '400':
          description: 'List operation failed.'
Compliant example:
paths:
  '/v1/things/':
    get:
      operationId: list_things
      parameters:
        - name: start
          in: query
          description: 'The token representing the first item to return.'
          required: false
          schema:
            type: string
            minLength: 1
            maxLength: 64
            pattern: '[a-zA-Z0-9 ]+'
        - name: limit
          in: query
          description: 'The number of items to return per page.'
          required: false
          schema:
            type: integer
            format: int32
            minimum: 0
            maximum: 100
            default: 10
      responses:
        '200':
          description: 'Resources retrieved successfully!'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ThingCollection'
        '400':
          description: 'List operation failed.'

ibm-property-attributes

Rule id: ibm-property-attributes
Description: This rule performs the following checks on schemas and schema properties:
Numeric schemas (type=integer, type=number):
  • minimum must not be greater than maximum.
  • minimum must not be defined for a schema type other than integer or number.
  • maximum must not be defined for a schema type other than integer or number.
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.
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

ibm-property-casing-convention

Rule id: ibm-property-casing-convention
Description: Schema property names should follow a specific case convention, with the default being snake case.
Severity: error
OAS Versions: oas3
Configuration: This rule can be configured to enforce a specific case convention for schema property names. To configure the rule, set the functionOptions field within the rule definition to be an object that is the appropriate configuration to be used by Spectral's casing() function [1] to enforce the desired case convention for property names.

The default configuration object provided in the rule definition is:

{
  type: 'snake'
}

To enforce a different case convention for property names, you'll need to replace this rule with a new rule within your custom ruleset and modify the configuration such that the value of the type field specifies the desired case convention. For example, to enforce camel case for property names, the configuration object would look like this:

{
  type: 'camel'
}
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

ibm-property-consistent-name-and-type

Rule id: ibm-property-consistent-name-and-type
Description: Like-named schema properties (from different schemas) should have the same type to ensure consistency throughout the API definition.

This rule is disabled by default. Enable it in your Spectral config file to utilize this validation.
Severity: off
OAS Versions: oas3
Non-compliant example:
components:
  schemas:
    Thing:
      type: object
      properties:
        name:
          description: The name of the Thing.
          type: string
    OtherThing:
      type: object
      properties:
        name:
          description: The name of the OtherThing.
          type: integer # The property 'name' should use consistent types throughout the API
Compliant example:
components:
  schemas:
    Thing:
      type: object
      properties:
        name:
          description: The name of the Thing.
          type: string
    OtherThing:
      type: object
      properties:
        name:
          description: The name of the OtherThing.
          type: string

ibm-property-description

Rule id: ibm-property-description
Description: Schema properties should have a non-empty description.
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

ibm-ref-pattern

Rule id: ibm-ref-pattern
Description: This rule checks each $ref value to make sure it follows the correct pattern based on the type of object it references. For example, a reference to a schema should follow the pattern #/components/schemas/<schema-name>.

Here is the full set of valid patterns for $ref values:

  • #/components/callbacks/<name>
  • #/components/examples/<name>
  • #/components/headers/<name>
  • #/components/links/<name>
  • #/components/parameters/<name>
  • #/components/requestBodies/<name>
  • #/components/responses/<name>
  • #/components/schemas/<name>
  • #/components/securitySchemes/<name>
The validator uses the $ref property's location within the API definition to determine the type of object being referenced. For example, if the $ref property is found where a parameter object is expected, then the validator assumes that the $ref is referencing a parameter object, and that the reference should follow the pattern #/components/parameters/<param-name>. Incidentally, this rule also has the effect of ensuring that various types of objects are defined in their proper locations within the API definition's componentsfield.
Severity: warn
OAS Versions: oas3
Non-compliant example:
components:
  schemas:
    Foo:
      type: object
      properties:
        bar:
          $ref: '#/definitions/Bar'
definitions:
  Bar:
    type: object
    properties:
      bar:
        type: string
Compliant example:
components:
  schemas:
    Foo:
      type: object
      properties:
        bar:
          $ref: '#/components/schemas/Bar'
    Bar:
      type: object
      properties:
        bar:
          type: string

ibm-request-and-response-content

Rule id: ibm-request-and-response-content
Description: Each request body and non-204 response should have a content field.
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'

ibm-requestbody-is-object

Rule id: ibm-requestbody-is-object
Description: Each non-form-based request body should be defined as an object.
Severity: warn
OAS Versions: oas3
Non-compliant example:
requestBody:
  content:
    application/json:
      schema:
        type: string
Compliant example:
requestBody:
  content:
    application/json:
      schema:
        type: object
        properties:
          prop1:
            type: string

ibm-requestbody-name

Rule id: ibm-requestbody-name
Description: The x-codegen-request-body-name extension can be set on an operation to provide a language-agnostic name for any body parameter that might appear within generated SDK code. For operations that support multipart-form-based request body content, this isn't necessary since the names of the form parameters are inferred from the property names within the request body schema. However, for operations that support other non-form-based request body content (json-based and non-json-based content alike), it is a good practice to provide the request body name via the extension, especially in situations where there is no other way to infer a logical name for the operation's body parameter.

This rule analyzes each operation to determine if a request body name is needed, and if so, checks to make sure that the x-codegen-request-body-name extension is set on the operation.

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

ibm-resource-response-consistency

Rule id: ibm-requestbody-name
Description: Synchronous responses for create-style POST or update (PUT/PATCH) operations on a given resource instance should return the canonical schema for the resource, which is the schema returned in the GET operation on the single-instance path (e.g. `/resources/{id}`). Synchronous responses for bulk replace (PUT) operations should return the collection schema, which is the schema returned in the GET operation on the collection path (e.g. `/resources`).
Severity: warn
OAS Versions: oas3
Non-compliant example:
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'

ibm-response-status-codes

Rule id: ibm-response-status-codes
Description: This rule performs a few different checks on the status codes used in operation responses:
  • The use of the 422 - Unprocessable Entity status code is discouraged. Use 400 - Bad Request instead.
  • The use of the 302 - Found status code is discouraged. Use 303 - See Other or 307 - Temporary Redirect instead.
  • The 101 - Switching Protocols status code should not be used if any success status codes (2xx) are also present.
  • Each operation should include at least one success status code (2xx). An exception to this is when the 101 - Switching Protocols status code is used, which should be extremely rare (it's normally used with websockets).
  • A 204 - No Content response should not include content.
  • A non-204 success status code (e.g. 200 - OK, 201 - Created, etc.) should include content.
  • A "create"-type operation must return either a 201 - Created or a 202 - Accepted status code. The one exception is, it may return a 204 - No Content status code if the corresponding GET request for the same resource also returns a 204 - No Content status code (which indicates there is no body representation for the resource).
  • A PUT operation must return either a 200 - OK, 201 - Created, or 202 - Accepted status code.
  • A PATCH operation must return either a 200 - OK or a 202 - Accepted status code.
  • 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'

ibm-schema-casing-convention

Rule id: ibm-schema-casing-convention
Description: Schema names (the keys in `components -> schemas`) should follow the "upper camel case" convention as required by the IBM Cloud API Handbook. Note that acronyms are allowed to be capitalized.
Severity: warn
OAS Versions: oas3
Configuration: This rule can be configured to define the specific regular expression used to enforce a case convention for schema name values. To configure the rule, set the functionOptions field within the rule definition to be an object that is the appropriate configuration to be used by Spectral's pattern() function [1] to enforce the desired case convention for schema name values.

The default configuration object provided in the rule definition is:

{
  match: '/^[A-Z]+[a-z0-9]+([A-Z]+[a-z0-9]*)*$/'
}

To enforce a different case convention for schema name values, you'll need to replace this rule with a new rule within your custom ruleset and modify the configuration such that the value of the match field specifies the desired case convention. For example, to disallow capitalized acronymns for schema names, the configuration object would look like this:

{
  match: '/^[A-Z][a-z0-9]+([A-Z][a-z0-9]+)*$/'
}
Non-compliant example:
components:
  schemas:
    specific_thing:
      type: object
      properties:
        ...
Compliant example:
components:
  schemas:
    SpecificThing:
      type: object
      properties:
        ...

ibm-schema-description

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:
        ...

ibm-schema-keywords

Rule id: ibm-schema-keywords
Description: This rule verifies that only certain keywords (fields) are used when defining schemas and schema properties in an OpenAPI 3.1.x document. The allowable keywords are configurable (see the Configuration section below).
Severity: error
OAS Versions: oas3_1
Configuration: This rule supports a configuration object that specifies the set of keywords that are allowed within a schema or schema property.

The default configuration object provided with the rule is:

{
  keywordAllowList: [
    '$ref',
    'additionalProperties',
    'allOf',
    'anyOf',
    'default',
    'description',
    'discriminator',
    'enum',
    'example',
    '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',
    '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

ibm-schema-naming-convention

Rule id: ibm-schema-naming-convention
Description: The name of each schema should follow the IBM Cloud API Handbook schema naming conventions.

The rule checks the names of collection schemas, resource collection element schemas, creation/replacement schemas, and patch schemas against the name of the associated canonical schema to ensure the names follow the guidelines.

Severity: warn
OAS Versions: oas3
Non-compliant example:
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'

ibm-schema-type

Rule id: ibm-schema-type
Description: Schemas and schema properties should have a non-empty type field.

This rule is disabled by default. Enable it in your Spectral config file to utilize this validation.
Severity: off
OAS Versions: oas3
Non-compliant example:
components:
  schemas:
    Thing:
      description: An underspecified schema
        ...
Compliant example:
components:
  schemas:
    Thing:
      type: string
      description: An string schema
        ...

ibm-schema-type-format

Rule id: ibm-schema-type-format
Description: Schemas and schema properties must use a valid combination of the type and format fields [1]. The following table defines the valid combinations:
TypeFormats
string
  • binary
  • byte
  • crn
  • date
  • date-time
  • email
  • identifier
  • password
  • url
  • uuid
boolean
integer
  • int32
  • int64
number
  • float
  • double
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

ibm-sdk-operations

Rule id: ibm-sdk-operations
Description: This rule validates the structure of values specified for the x-sdk-operations extension, using this JSON Schema document.
Severity: warn
OAS Versions: oas3
Non-compliant example: n/a
Compliant example: n/a

ibm-securityscheme-attributes

Rule id: ibm-securityscheme-attributes
Description: Performs a series of validations on the content within security schemes to ensure they comply with the constraints outlined in the OpenAPI Specification.

Specifically, the rule will perform these checks:

  1. Each security scheme must specify the type property. Valid values for the type property are:
    • apiKey
    • http
    • oauth2
    • openIdConnect
  2. A security scheme with type apiKey must specify the name and in properties. Valid values for the in property are:
    • cookie
    • header
    • query
  3. A security scheme with type http must specify the scheme property.
  4. 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.

  5. 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

ibm-securityschemes

Rule id: ibm-securityschemes
Description: Verifies the security schemes and security requirement objects.

Specifically, the rule will perform these checks:

  1. The name used within a security requirement object must correspond to a security scheme that is properly defined in "components.securitySchemes".
  2. Each security scheme defined in "components.securitySchemes" should be referenced by at least one security requirement object.
  3. Each scope referenced within a security requirement object for an oauth2-type security scheme must be defined within that security scheme.
  4. Each scope that is defined within an oath2-type security scheme should be referenced by at least one security requirement object.
  5. 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

ibm-server-variable-default-value

Rule id: ibm-server-variable-default-value
Description: Server variables should have a default value.
Severity: warn
OAS Versions: oas3
Non-compliant example:
servers:
- url: https://{region}.myservice.cloud.ibm.com
  description: The region-based endpoints available for My Service.
  variables:
    region:
      description: >-
        The name of the region, which should be one of:
          "global", "us-south", "us-east", "us-west", "us-north"
Compliant example:
servers:
- url: https://{region}.myservice.cloud.ibm.com
  description: The region-based endpoints available for My Service.
  variables:
    region:
      default: global
      description: >-
        The name of the region, which should be one of:
          "global", "us-south", "us-east", "us-west", "us-north"

ibm-string-attributes

Rule id: ibm-string-attributes
Description: This rule checks to make sure that string schema properties define the pattern, minLength and maxLength fields in order to clearly define the set of valid values for the property. [1].

Note that these checks are bypassed for the following scenarios:

  • All checks are bypassed for string schemas that are used only within an operation response.
  • All checks are bypassed for string schemas that contain an enum field.
  • The check for the pattern field is bypassed if format is set to binary, byte, date, date-time, or url.
  • The check for the minLength field is bypassed if format is set to date, identifier, or url.
  • The check for the maxLength field is bypassed if format is set to date.

This rule also checks non-string schema properties to make sure they do not define the code>pattern, minLength and maxLength fields since these fields are applicable only for string schemas.

Severity: warn
OAS Versions: oas3
Non-compliant example:
components:
  schemas:
    Thing:
      description: A Thing instance.
      type: object
      properties:
        thing_id:
          description: The unique identifier of the Thing instance.
          type: string
Compliant example:
components:
  schemas:
    Thing:
      description: A Thing instance.
      type: object
      properties:
        thing_id:
          description: The unique identifier of the Thing instance.
          type: string
          pattern: '^[a-zA-Z0-9]*$'
          minLength: 8
          maxLength: 64
          example: 'ab38dd26z'

ibm-success-response-example

Rule id: ibm-success-response-example
Description: Response examples should be provided in the schema object - or as a sibling to the schema object - within each response content field entry, in order to aid in the generation of API reference documentation.
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'

ibm-summary-sentence-style

Rule id: ibm-summary-sentence-style
Description: An operation's summary field should contain a very brief description of the operation and should not have a trailing period.
Severity: warn
OAS Versions: oas3
Non-compliant example:
paths:
  /v1/things
    get:
      operationId: list_things
      summary: List the Thing objects.
      description: Retrieve a paginated collection of Thing instances.
Compliant example:
paths:
  /v1/things
    get:
      operationId: list_things
      summary: List things
      description: Retrieve a paginated collection of Thing instances.

ibm-unevaluated-properties

Rule id: ibm-unevaluated-properties
Description: This rule ensures that unevaluatedProperties is not enabled within a schema. It checks to make sure that if the unevaluatedProperties field is set on a schema, then it is set to the value false (i.e. disabled).
Severity: error
OAS Versions: oas3_1
Non-compliant example:
components:
  schemas:
    Thing:
      type: object
      properties:
        id:
          type: string
        metadata:
          description: additional info about the thing
          type: object
      unevaluatedProperties:
        type: string
Compliant example:
components:
  schemas:
    Thing:
      type: object
      properties:
        id:
          type: string
        metadata:
          description: additional info about the thing
          type: object
      unevaluatedProperties: false

ibm-unique-parameter-request-property-names

Rule id: ibm-unique-parameter-request-property-names
Description: The IBM Cloud API Handbook discourages the use of path parameter names that match any of the names of top-level properties in the operation's request body schema. The primary justification for this guidance is that if the names of operation parameters collide with the names of top-level request body properties, then it creates ambiguity and perhaps a lack of clarity for users of the API. In fact, the guidance applies equally well for all parameter types, not just path parameters.

And more specifically, IBM's OpenAPI SDK Generator will "explode" an operation's request body under certain circumstances in order to simplify the application code required to invoke the operation. This means that, instead of representing the operation's request body as a single operation parameter, the generator will expose each of the properties defined in the operation's request body schema such that they appear to be individual operation parameters. This optimization makes it easier for an SDK user to construct an instance of the request body schema (class, struct, etc.) when invoking the operation.

Because the request body schema properties are exposed as operation parameters, the generator must detect if there are any name collisions between these schema properties and the operation's other parameters. The generator will rename the request body schema properties if any collisions are detected, but the names computed by the generator are not optimal from a usability standpoint, so it's better for the API to be defined such that the name collisions are avoided altogether.

This validation rule checks each operation for name collisions between the operation's parameters and its request body schema properties. An error is logged for each collision. Each of these errors should be addressed by renaming either the parameter or request body schema property to avoid the collision.

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

ibm-valid-path-segments

Rule id: ibm-valid-path-segments
Description: This rule validates the path segments within each path string found in the API. Specifically, the rule makes sure that any path segment containing a path parameter reference contains only that parameter reference and nothing more. For example, the path /v1/foos/_{foo_id}_ is invalid and should probably be /v1/foos/{foo_id}.
Severity: error
OAS Versions: oas3
Non-compliant example:
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
    ...

ibm-well-defined-dictionaries

Rule id: ibm-well-defined-dictionaries
Description: This rule validates that any dictionary schemas are well defined and that all values share a single type. Dictionaries are defined as object type schemas that have variable key names. They are distinct from model types, which are objects with pre-defined properties. A schema must not define both concrete properties and variable key names. Practically, this means a schema must explicitly define a `properties` object or an `additionalProperties` schema, but not both. If used, the `additionalProperties` schema must define a concrete type. 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