Agent skill
spectral-linting
Spectral API linting configuration, rules, and validation for OpenAPI specs
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/spectral-linting
SKILL.md
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
# or use npx
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:
# Critical rules (errors)
oas3-valid-schema-example: error
operation-operationId: error
operation-success-response: error
# Important rules (warnings)
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:
# .spectral.yml - OpenAPI linting configuration
# Extend Spectral's built-in OpenAPI ruleset
extends: spectral:oas
# Custom rules and severity overrides
rules:
# ========================================
# Critical Rules (error = must fix)
# ========================================
# All examples must be valid against their schemas
oas3-valid-schema-example: error
# Every operation must have an operationId
operation-operationId: error
# Every operation must have a success response (200-299)
operation-success-response: error
# All tags used in operations must be defined
operation-tag-defined: error
# Info section must have description
info-description: error
# ========================================
# Important Rules (warn = should fix)
# ========================================
# Operations should have descriptions
operation-description: warn
# Operations should have tags
operation-tags: warn
# Parameters should have descriptions
operation-parameters: warn
# Paths should use kebab-case
path-keys-no-trailing-slash: warn
# ========================================
# Optional Rules (info = nice to have)
# ========================================
# Contact information recommended
info-contact: info
# License information recommended
info-license: info
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 # MUST fix - blocks merge
rule-name: warn # SHOULD fix - doesn't block
rule-name: info # OPTIONAL - informational only
rule-name: off # Disabled - not checked
When to use each:
error: Critical issues that break spec or cause generation failureswarn: Important issues that should be fixed but don't break functionalityinfo: Nice-to-have improvementsoff: Rule doesn't apply or is too strict
Custom Rules
Add custom rules for project-specific requirements:
rules:
# Custom rule: Require x-auditmation-operation metadata
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
# Custom rule: Require examples in responses
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
# Custom rule: Consistent error response structure
require-error-schema:
description: Error responses should use standard error schema
given: $.paths.*.*.responses[?(@property >= 400)]
severity: warn
then:
field: content.application/json.schema.$ref
function: pattern
functionOptions:
match: "#/components/schemas/Error"
Disabling Rules
Disable rules with justification:
rules:
# Disabled: Legacy API doesn't follow this pattern
# Date: 2024-10-15
# Reason: Historical API design, can't change without breaking clients
operation-description: off
# Disabled: Service doesn't use tags
# Date: 2024-10-15
# Reason: Small API, tags add unnecessary complexity
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:
# spectral:disable operation-description
summary: Legacy endpoint
operationId: legacyOperation
# ... rest of operation
Use sparingly:
- Only for exceptions
- Document why in comments
- Prefer fixing the issue over disabling
đĸ GUIDELINES
Running Spectral
Basic usage:
# Lint single file
npx @stoplight/spectral-cli lint api.yml
# Lint with custom config
npx @stoplight/spectral-cli lint -r .spectral.yml api.yml
# Output formats
npx @stoplight/spectral-cli lint api.yml -f json
npx @stoplight/spectral-cli lint api.yml -f html > report.html
# Lint multiple files
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:
# .github/workflows/ci.yml
- name: Lint API Spec
run: npx @stoplight/spectral-cli lint api.yml
Common Rules to Enable
For strict API design:
rules:
# Require descriptions everywhere
operation-description: error
operation-parameters: error
components-examples: error
# Require tags
operation-tags: error
operation-tag-defined: error
# Require 2xx and 4xx responses
operation-success-response: error
operation-4xx-response: warn
# Schema validation
oas3-valid-schema-example: error
typed-enum: error
# Naming conventions
path-keys-no-trailing-slash: error
path-params: error
For relaxed API design:
rules:
# Only critical validation
oas3-valid-schema-example: error
operation-operationId: error
# Everything else is warnings or off
operation-description: warn
operation-tags: off
JSONPath Expressions
Target specific parts of spec:
rules:
# All GET operations
given: $.paths.*.get
# All operations (any HTTP method)
given: $.paths.*[get,post,put,delete,patch]
# All parameters
given: $.paths.*.*.parameters[*]
# All 2xx responses
given: $.paths.*.*.responses[?(@property >= 200 && @property < 300)]
# All schemas
given: $.components.schemas[*]
Functions:
truthy- field must exist and not be emptyfalsy- field must not exist or be emptypattern- field must match regexlength- field length validationschema- validate against JSON schema
Multiple Rulesets
Extend multiple rulesets:
extends:
- spectral:oas
- spectral:asyncapi
# - custom-ruleset.yml
rules:
# Your rules
Create custom ruleset file:
# custom-auditmation-rules.yml
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:
# .spectral.yml
extends:
- spectral:oas
- ./custom-auditmation-rules.yml
Validation
Check .spectral.yml Exists
# Check if .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
# Validate YAML 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
# 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
# Run spectral lint on api.yml
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
# Check critical rules are enabled
if [ -f .spectral.yml ]; then
echo "Checking critical rules..."
# Check oas3-valid-schema-example
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
# Check operation-operationId
if grep -q "operation-operationId.*error" .spectral.yml; then
echo " â
operation-operationId: error"
else
echo " â ī¸ Should set operation-operationId to error"
fi
# Check operation-success-response
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
# validate-spectral.sh - Validate Spectral configuration and run linting
echo "=== Spectral API Linting Validation ==="
echo ""
ERRORS=0
# 1. Check .spectral.yml exists
echo "1. Configuration File:"
if [ -f .spectral.yml ]; then
echo " â
.spectral.yml exists"
# Validate YAML syntax
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 ""
# 2. Check extends spectral:oas
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 ""
fi
# 3. Check critical rules
if [ -f .spectral.yml ]; then
echo "3. Critical Rules:"
if grep -q "oas3-valid-schema-example.*error" .spectral.yml; then
echo " â
oas3-valid-schema-example: error"
else
echo " â ī¸ Recommend: oas3-valid-schema-example: error"
fi
if grep -q "operation-operationId.*error" .spectral.yml; then
echo " â
operation-operationId: error"
else
echo " â ī¸ Recommend: operation-operationId: error"
fi
if grep -q "operation-success-response.*error" .spectral.yml; then
echo " â
operation-success-response: error"
else
echo " â ī¸ Recommend: operation-success-response: error"
fi
echo ""
fi
# 4. Check Spectral is available
echo "4. Spectral Installation:"
if command -v spectral &> /dev/null; then
VERSION=$(spectral --version)
echo " â
Spectral installed: $VERSION"
elif command -v npx &> /dev/null; then
echo " â
Can use npx @stoplight/spectral-cli"
else
echo " â Spectral not available (install with: npm install -g @stoplight/spectral-cli)"
ERRORS=$((ERRORS + 1))
fi
echo ""
# 5. Run lint on api.yml
echo "5. API Spec Linting:"
if [ -f api.yml ]; then
echo " Found api.yml, running lint..."
echo ""
if command -v spectral &> /dev/null; then
LINT_CMD="spectral lint api.yml"
elif command -v npx &> /dev/null; then
LINT_CMD="npx @stoplight/spectral-cli lint api.yml"
else
echo " â Cannot run lint - Spectral not available"
ERRORS=$((ERRORS + 1))
fi
if [ -n "$LINT_CMD" ]; then
if $LINT_CMD; then
echo ""
echo " â
API spec passes linting"
else
echo ""
echo " â API spec has linting errors"
ERRORS=$((ERRORS + 1))
fi
fi
else
echo " â ī¸ No api.yml found to lint"
fi
echo ""
# Summary
if [ $ERRORS -eq 0 ]; then
echo "=== â
VALIDATION PASSED ==="
exit 0
else
echo "=== â VALIDATION FAILED ($ERRORS errors) ==="
exit 1
fi
Common Issues
Issue: Spectral not found
Solution:
# Install globally
npm install -g @stoplight/spectral-cli
# Or use npx (no install needed)
npx @stoplight/spectral-cli lint api.yml
Issue: Many warnings overwhelming output
Solution:
# Reduce verbosity by turning some rules off
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:
# Use --verbose to see rule evaluation
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:
# In api.yml
paths:
/users:
get:
operationId: listUsers # Add this
tags:
- Users # Must be in global tags
responses:
'200': # Must have success response
description: Success
Anti-Patterns
â BAD: Disabling all rules
rules:
oas3-valid-schema-example: off
operation-operationId: off
operation-success-response: off
# Everything disabled
â GOOD: Enable strict validation
rules:
oas3-valid-schema-example: error
operation-operationId: error
operation-success-response: error
â BAD: No .spectral.yml
# No configuration, using defaults
# No customization, no documentation
â GOOD: Explicit configuration
# .spectral.yml with documented rules
extends: spectral:oas
rules:
# Critical rules
oas3-valid-schema-example: error
# ... with comments explaining choices
â BAD: Inline disables everywhere
paths:
/endpoint1:
get:
# spectral:disable operation-description
...
/endpoint2:
post:
# spectral:disable operation-description
...
â GOOD: Fix the issues or disable globally with justification
rules:
# Disabled: Legacy API pattern
operation-description: off
Integration
Pre-commit Hook
# .git/hooks/pre-commit
#!/bin/bash
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
# .github/workflows/lint-api.yml
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"
}
}
Didn't find tool you were looking for?