| name | spectral-linting |
| description | Spectral API linting configuration, rules, and validation for OpenAPI specs |
API Linting Configuration
🚨 CRITICAL RULES
1. Use Spectral for OpenAPI Linting
ALL api.yml files MUST be linted with Spectral before merge.
Install Spectral:
npm install -g @stoplight/spectral-cli
npx @stoplight/spectral-cli lint api.yml
2. Minimum .spectral.yml Configuration
Every module SHOULD have a .spectral.yml file in the module root:
extends: spectral:oas
rules:
oas3-valid-schema-example: error
operation-operationId: error
operation-success-response: error
operation-description: warn
operation-tags: warn
info-description: error
3. Zero Errors Before Merge
- ❌ API specs with linting errors CANNOT be merged
- ⚠️ Warnings should be fixed but don't block merge
- ℹ️ Info-level issues are optional
🟡 STANDARD RULES
Standard .spectral.yml Template
Basic configuration:
extends: spectral:oas
rules:
oas3-valid-schema-example: error
operation-operationId: error
operation-success-response: error
operation-tag-defined: error
info-description: error
operation-description: warn
operation-tags: warn
operation-parameters: warn
path-keys-no-trailing-slash: warn
Spectral Built-in Rules
Spectral:oas includes these rules by default:
| Rule | Default | Description |
|---|
oas3-valid-schema-example | warn | Examples must validate against schemas |
operation-operationId | warn | Operations should have operationId |
operation-success-response | warn | Operations should have 2xx response |
operation-description | warn | Operations should have description |
operation-tags | warn | Operations should have tags |
operation-tag-defined | warn | Tags must be defined in global tags |
info-description | warn | Info section should have description |
info-contact | off | Info section should have contact |
info-license | off | Info section should have license |
path-keys-no-trailing-slash | warn | Paths should not end with / |
Severity Levels
Four severity levels:
rules:
rule-name: error
rule-name: warn
rule-name: info
rule-name: off
When to use each:
error: Critical issues that break spec or cause generation failures
warn: Important issues that should be fixed but don't break functionality
info: Nice-to-have improvements
off: Rule doesn't apply or is too strict
Custom Rules
Add custom rules for project-specific requirements:
rules:
require-auditmation-operation-tag:
description: Operations must have x-auditmation-operation metadata
given: $.paths.*[get,post,put,delete,patch]
severity: error
then:
field: x-auditmation-operation
function: truthy
require-response-examples:
description: Success responses should have examples
given: $.paths.*.*.responses[?(@property >= 200 && @property < 300)]
severity: warn
then:
field: content.application/json.example
function: truthy
require-error-schema:
description: Error responses should use standard error schema
Disabling Rules
Disable rules with justification:
rules:
operation-description: off
operation-tags: off
When to disable:
- ✅ Legacy APIs that can't be changed
- ✅ Rules that don't fit your use case
- ✅ Temporarily during development
- ❌ To avoid fixing legitimate issues
- ❌ Without documenting why
Inline Overrides
Disable specific rules for specific operations:
paths:
/legacy/endpoint:
get:
summary: Legacy endpoint
operationId: legacyOperation
Use sparingly:
- Only for exceptions
- Document why in comments
- Prefer fixing the issue over disabling
🟢 GUIDELINES
Running Spectral
Basic usage:
npx @stoplight/spectral-cli lint api.yml
npx @stoplight/spectral-cli lint -r .spectral.yml api.yml
npx @stoplight/spectral-cli lint api.yml -f json
npx @stoplight/spectral-cli lint api.yml -f html > report.html
npx @stoplight/spectral-cli lint **/*.yml
In package.json scripts:
{
"scripts": {
"lint:api": "spectral lint api.yml",
"lint:api:fix": "spectral lint api.yml --format pretty"
}
}
In CI/CD:
- name: Lint API Spec
run: npx @stoplight/spectral-cli lint api.yml
Common Rules to Enable
For strict API design:
rules:
operation-description: error
operation-parameters: error
components-examples: error
operation-tags: error
operation-tag-defined: error
operation-success-response: error
operation-4xx-response: warn
oas3-valid-schema-example: error
typed-enum: error
path-keys-no-trailing-slash: error
path-params: error
For relaxed API design:
rules:
oas3-valid-schema-example: error
operation-operationId: error
operation-description: warn
operation-tags: off
JSONPath Expressions
Target specific parts of spec:
rules:
given: $.paths.*.get
given: $.paths.*[get,post,put,delete,patch]
given: $.paths.*.*.parameters[*]
given: $.paths.*.*.responses[?(@property >= 200 && @property < 300)]
given: $.components.schemas[*]
Functions:
truthy - field must exist and not be empty
falsy - field must not exist or be empty
pattern - field must match regex
length - field length validation
schema - validate against JSON schema
Multiple Rulesets
Extend multiple rulesets:
extends:
- spectral:oas
- spectral:asyncapi
rules:
Create custom ruleset file:
rules:
require-x-auditmation-operation:
description: Operations must have x-auditmation-operation
given: $.paths.*[get,post,put,delete,patch]
severity: error
then:
field: x-auditmation-operation
function: truthy
require-examples:
description: All schemas should have examples
given: $.components.schemas[*]
severity: warn
then:
field: example
function: truthy
Then extend it:
extends:
- spectral:oas
- ./custom-auditmation-rules.yml
Validation
Check .spectral.yml Exists
if [ -f .spectral.yml ]; then
echo "✅ PASS: .spectral.yml found"
else
echo "⚠️ WARN: No .spectral.yml (using default rules)"
fi
Validate .spectral.yml Syntax
if [ -f .spectral.yml ]; then
if command -v yq &> /dev/null; then
if yq . .spectral.yml > /dev/null 2>&1; then
echo "✅ PASS: Valid YAML syntax"
else
echo "❌ FAIL: Invalid YAML syntax"
exit 1
fi
else
echo "⚠️ WARN: yq not installed, cannot validate YAML"
fi
fi
Check Extends Spectral:oas
if [ -f .spectral.yml ]; then
if grep -q "extends.*spectral:oas" .spectral.yml; then
echo "✅ PASS: Extends spectral:oas"
else
echo "⚠️ WARN: Should extend spectral:oas"
fi
fi
Run Spectral Lint
if command -v spectral &> /dev/null || command -v npx &> /dev/null; then
echo "Running Spectral lint..."
if [ -f api.yml ]; then
if npx @stoplight/spectral-cli lint api.yml; then
echo "✅ PASS: API spec passes linting"
else
echo "❌ FAIL: API spec has linting errors"
exit 1
fi
else
echo "⚠️ WARN: No api.yml found"
fi
else
echo "⚠️ WARN: Spectral not installed"
fi
Check for Critical Rules
if [ -f .spectral.yml ]; then
echo "Checking critical rules..."
if grep -q "oas3-valid-schema-example.*error" .spectral.yml; then
echo " ✅ oas3-valid-schema-example: error"
else
echo " ⚠️ Should set oas3-valid-schema-example to error"
fi
if grep -q "operation-operationId.*error" .spectral.yml; then
echo " ✅ operation-operationId: error"
else
echo " ⚠️ Should set operation-operationId to error"
fi
if grep -q "operation-success-response.*error" .spectral.yml; then
echo " ✅ operation-success-response: error"
else
echo " ⚠️ Should set operation-success-response to error"
fi
fi
Complete Validation Script
#!/bin/bash
echo "=== Spectral API Linting Validation ==="
echo ""
ERRORS=0
echo "1. Configuration File:"
if [ -f .spectral.yml ]; then
echo " ✅ .spectral.yml exists"
if command -v yq &> /dev/null; then
if yq . .spectral.yml > /dev/null 2>&1; then
echo " ✅ Valid YAML syntax"
else
echo " ❌ Invalid YAML syntax"
ERRORS=$((ERRORS + 1))
fi
fi
else
echo " ⚠️ No .spectral.yml (will use defaults)"
fi
echo ""
if [ -f .spectral.yml ]; then
echo "2. Ruleset Configuration:"
if grep -q "extends.*spectral:oas" .spectral.yml; then
echo " ✅ Extends spectral:oas"
else
echo " ⚠️ Should extend spectral:oas"
fi
echo ""
[ -f .spectral.yml ];
grep -q .spectral.yml;
grep -q .spectral.yml;
grep -q .spectral.yml;
-v spectral &> /dev/null;
VERSION=$(spectral --version)
-v npx &> /dev/null;
ERRORS=$((ERRORS + ))
[ -f api.yml ];
-v spectral &> /dev/null;
LINT_CMD=
-v npx &> /dev/null;
LINT_CMD=
ERRORS=$((ERRORS + ))
[ -n ];
;
ERRORS=$((ERRORS + ))
[ -eq 0 ];
0
1
Common Issues
Issue: Spectral not found
Solution:
npm install -g @stoplight/spectral-cli
npx @stoplight/spectral-cli lint api.yml
Issue: Many warnings overwhelming output
Solution:
rules:
operation-description: off
operation-tags: off
info-contact: off
Issue: Custom rule not working
Check:
- JSONPath expression is correct
- Field name matches spec
- Function is valid Spectral function
- Severity is set
Debug:
npx @stoplight/spectral-cli lint api.yml --verbose
Issue: Valid spec fails linting
Common causes:
- Example doesn't match schema
- Missing operationId
- Missing success response
- Tag not defined in global tags
Fix:
paths:
/users:
get:
operationId: listUsers
tags:
- Users
responses:
'200':
description: Success
Anti-Patterns
❌ BAD: Disabling all rules
rules:
oas3-valid-schema-example: off
operation-operationId: off
operation-success-response: off
✅ GOOD: Enable strict validation
rules:
oas3-valid-schema-example: error
operation-operationId: error
operation-success-response: error
❌ BAD: No .spectral.yml
✅ GOOD: Explicit configuration
extends: spectral:oas
rules:
oas3-valid-schema-example: error
❌ BAD: Inline disables everywhere
paths:
/endpoint1:
get:
...
/endpoint2:
post:
...
✅ GOOD: Fix the issues or disable globally with justification
rules:
operation-description: off
Integration
Pre-commit Hook
if [ -f api.yml ]; then
echo "Linting API spec..."
if ! npx @stoplight/spectral-cli lint api.yml; then
echo "❌ API linting failed. Fix errors before committing."
exit 1
fi
fi
GitHub Actions
name: Lint API Spec
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 18
- name: Lint API
run: npx @stoplight/spectral-cli lint api.yml
npm Scripts
{
"scripts": {
"lint:api": "spectral lint api.yml",
"lint:api:json": "spectral lint api.yml -f json",
"lint:api:html": "spectral lint api.yml -f html -o api-lint-report.html",
"test": "npm run lint:api && jest"
}
}