Spectral Documentation

repository·develop·Indexed 25 days ago

https://github.com/stoplightio/spectral

Spectral is a generic YAML/JSON linter used for API governance, enabling the creation of custom rulesets and style guides for OpenAPI, AsyncAPI, and Arazzo documents. It features a CLI, built-in and custom functions, JSON path support, and a suite of supporting packages including @stoplight/spectral-formatters, @stoplight/spectral-ref-resolver, @stoplight/spectral-ruleset-bundler, and @stoplight/spectral-ruleset-migrator.

Tokens
48.2K
Snippets
129
Records
288
Agent score
78%

What's inside Spectral

  1. Overview of Spectral capabilities

    develop

    Spectral is a JSON/YAML linter that supports:

    • Custom Rulesets: Create rules to lint specific JSON or YAML objects.
    • Ready-to-use Rulesets: Built-in support for OpenAPI v2 & v3.x, AsyncAPI, and Arazzo v1.
    • JSON Path Support: Apply rules to specific parts of objects using JSON path.
    • Built-in Functions: Includes pattern checks, parameter checks, alphabetical ordering, and more.
    • Custom Functions: Extend functionality by writing your own logic.
  2. Understand Spectral core concepts: Rules, Functions, and Rulesets

    develop

    Spectral's architecture is built on three fundamental building blocks used to validate API descriptions (like OpenAPI, AsyncAPI, or Arazzo):

    • Rules: These define the logic for linting. A rule filters an object down to specific target values and specifies which Functions to use to evaluate those values.
    • Functions: The atomic units of validation. A function accepts a value and returns issues if that value does not meet the expected criteria.
    • Rulesets: A collection or container that organizes multiple rules and functions into a single executable unit.

    You can use Spectral's bundled core functions and rulesets for OpenAPI (v2/v3), AsyncAPI (v2/v3), and Arazzo (v1), or you can create your own to enforce custom API Style Guides.

  3. Modify existing rules in an extended ruleset

    develop

    To replace or override a rule defined in an extended ruleset, add a rule to your own ruleset using the exact same name. This allows you to redefine the description, given, or then logic of the original rule.

    extends: spectral:oas
    rules:
      tag-description:
        description: Please provide a description for each tag.
        given: $.tags[*]
        then:
          field: description
          function: truthy
  4. Migrate Spectral rulesets from YAML/JSON to JS

    develop

    The @stoplight/spectral-ruleset-migrator converts legacy Spectral ruleset formats (YAML/JSON) into valid JavaScript code (CommonJS or ESM). This is useful when you need to use functions or complex logic within your ruleset that cannot be expressed in static YAML.

    const { migrateRuleset } = require("@stoplight/spectral-ruleset-migrator");
    const fs = require("fs");
    const path = require("path");
    
    migrateRuleset(path.join(__dirname, "spectral.json"), {
      fs,
      format: "commonjs", // esm available too, but not recommended for now
    }).then(fs.promises.writeFile.bind(fs.promises, path.join(__dirname, ".spectral.js")));
  5. Load rulesets via HTTP server

    develop

    Since a ruleset is a standard JSON or YAML file, you can host it on any web server (e.g., Amazon S3, GitHub raw content) and reference it via its URL in the extends array. You can also pass a remote ruleset URL directly to the Spectral CLI using the -r flag.

    extends:
      - https://example.com/company-ruleset.yaml
    spectral lint -r https://example.com/some-ruleset.yml
  6. Disable specific rules from an extended ruleset

    develop

    If you have extended a ruleset with all its rules, you can disable specific rules by setting them to off within the rules object. This is useful when you want a broad ruleset but need to make exceptions for certain constraints.

    extends: [[spectral:oas, all]]
    rules:
      operation-operationId-unique: off
  7. Linting Code-First Workflows

    develop

    For code-first workflows where API descriptions are embedded in code (e.g., as comments or annotations), use a tool to export the specification to a file first, then run Spectral against that file.

    Example workflow using go-swagger:

    1. Generate the OpenAPI specification from code.
    2. Run spectral lint on the generated file.
    swagger generate spec -o ./tmp/openapi.json && spectral lint ./tmp/openapi.json
  8. Run Spectral CLI to lint documents

    develop
    Use the spectral lint command to validate YAML or JSON documents (such as OpenAPI v2/v3). You can lint a single file, multiple files, or use glob patterns to match multiple files at once. If no ruleset is specified via the --ruleset flag, Spectral looks for a default ruleset file (.spectral.yml, .spectral.yaml, .spectral.json, or .spectral.js) in the current working directory.
  9. Load rulesets via npm

    develop

    You can distribute rulesets as npm packages. This allows for easy versioning and bundling of custom functions. To use an npm-based ruleset, install the package via npm or yarn and reference the package name in the extends field. For browser-based usage or to avoid local installation, you can use a CDN like unpkg.com.

    # Using a local npm package
    extends:
      - example-spectral-ruleset
    
    # Using a CDN version
    extends:
      - "https://unpkg.com/example-spectral-ruleset@0.2.0"
  10. Write a Custom Rule

    develop

    A rule is defined within the rules object of a ruleset. Each rule consists of several key components:

    • description: A summary of the rule's purpose.
    • message: The error/warning message displayed when the rule fails. Supports interpolation like {{property}}.
    • severity: Defines the importance (e.g., warn, error).
    • given: A JSONPath Plus expression that targets the specific part of the document to lint.
    • then: Defines the validation logic using a function and functionOptions. Spectral provides built-in functions like truthy or pattern to power these checks.
    rules:
      paths-kebab-case:
        description: Paths should be kebab-case.
        message: "{{property}} should be kebab-case (lower-case and separated with hyphens)"
        severity: warn
        given: $.paths[*]~
        then:
          function: pattern
          functionOptions:
            match: "^(\/|[a-z0-9-.]+|{[a-zA-Z0-9_]+})+$"