Skip to main content

OpenAPI Specification (OAS) Validation

This document explains how to validate OpenAPI specifications generated by the OpenRegister application using automated tools.

Overview​

The OpenRegister application generates OpenAPI 3.1.0 specifications for each register, which need to be validated to ensure they conform to OpenAPI standards and follow best practices.

Validation Tool: Spectral​

We use Spectral by Stoplight, a comprehensive OpenAPI linter that checks for:

  • OpenAPI specification compliance
  • Best practices and conventions
  • Security considerations
  • Documentation quality
  • Schema consistency

Installation​

Install Spectral CLI globally:

npm install -g @stoplight/spectral-cli

Basic Usage​

1. Download OAS Specification​

First, retrieve the OAS specification from your register:

# Download OAS for a specific register (replace 15 with your register ID)
docker exec -u 33 master-nextcloud-1 bash -c "curl -s -u 'admin:admin' -H 'Content-Type: application/json' -X GET 'http://localhost/index.php/apps/openregister/api/registers/15/oas'" > oas-register-15.json

2. Validate with Spectral​

Run Spectral validation on the downloaded specification:

# Basic validation
spectral lint oas-register-15.json

# Detailed validation with specific ruleset
spectral lint oas-register-15.json --ruleset spectral:oas

# JSON output for programmatic processing
spectral lint oas-register-15.json --format json

# Fail on warnings (useful for CI/CD)
spectral lint oas-register-15.json --fail-severity warn

Understanding Spectral Output​

Spectral categorizes issues by severity:

  • Error: Specification violations that break OpenAPI compliance
  • Warning: Best practice violations or potential issues
  • Info: Suggestions for improvement
  • Hint: Minor style/consistency suggestions

Example output:

✖ 3 problems (1 error, 1 warning, 1 info, 0 hints)
1:1 error oas3-api-servers OpenAPI 'servers' must be present and non-empty array.
12:5 warning operation-tags Operation should have non-empty 'tags' array.
25:3 info operation-description Operation 'description' should be present and non-empty string.

Automated Testing Integration​

For Continuous Integration​

Create a test script that validates all register OAS specifications:

#!/bin/bash
# validate-oas.sh

echo 'Validating OpenAPI Specifications...'

# Get list of all registers
REGISTERS=$(docker exec -u 33 master-nextcloud-1 bash -c "curl -s -u 'admin:admin' -H 'Content-Type: application/json' -X GET 'http://localhost/index.php/apps/openregister/api/registers'" | jq -r '.results[].id')

FAILED=0

for REGISTER_ID in $REGISTERS; do
echo "Validating Register $REGISTER_ID..."

# Download OAS
docker exec -u 33 master-nextcloud-1 bash -c "curl -s -u 'admin:admin' -H 'Content-Type: application/json' -X GET 'http://localhost/index.php/apps/openregister/api/registers/$REGISTER_ID/oas'" > "oas-register-$REGISTER_ID.json"

# Validate with Spectral
if ! spectral lint "oas-register-$REGISTER_ID.json" --fail-severity error; then
echo "❌ Register $REGISTER_ID OAS validation failed"
FAILED=1
else
echo "✅ Register $REGISTER_ID OAS validation passed"
fi

# Clean up
rm "oas-register-$REGISTER_ID.json"
done

if [ $FAILED -eq 1 ]; then
echo "💥 OAS validation failed for one or more registers"
exit 1
else
echo "🎉 All OAS specifications are valid!"
fi

Common OAS Issues and Fixes​

1. Missing Server Information​

Error: OpenAPI 'servers' must be present and non-empty array

Fix: Ensure BaseOas.json includes proper server configuration:

{
"servers": [
{
"url": "http://localhost/apps/openregister/api",
"description": "OpenRegister API Server"
}
]
}

2. Missing Operation Tags​

Warning: Operation should have non-empty 'tags' array

Fix: Ensure all operations have tags for proper grouping:

$operation['tags'] = [$schema->getTitle()];

3. Missing Descriptions​

Info: Operation 'description' should be present and non-empty string

Fix: Add comprehensive descriptions to all operations:

$operation['description'] = 'Retrieve a list of all ' . $schema->getTitle() . ' objects';

4. Invalid Schema References​

Error: Property '$ref' does not exist

Fix: Ensure all $ref values point to valid schema definitions:

// Good
'$ref' => '#/components/schemas/Element'

// Bad
'$ref' => '#/components/schemas/NonExistentSchema'

Custom Spectral Rules​

Create custom validation rules for OpenRegister-specific requirements:

# .spectral.yml
extends: 'spectral:oas'

rules:
# Ensure all operations have pagination for collections
openregister-pagination:
given: '$.paths.*[get,post]'
then:
- field: 'parameters'
function: schema
functionOptions:
schema:
type: array
contains:
properties:
name:
enum: ['_limit', '_page', '_offset']

# Ensure error responses use Error schema
openregister-error-schema:
given: '$.paths.*.*.responses[4*,5*]'
then:
- field: 'content.application/json.schema.$ref'
function: pattern
functionOptions:
match: '#/components/schemas/Error'

Best Practices​

  1. Run validation regularly: Include OAS validation in your CI/CD pipeline
  2. Fix errors first: Address errors before warnings
  3. Document decisions: Use custom rules to enforce project-specific requirements
  4. Version control: Store validated OAS files for regression testing
  5. Monitor changes: Alert on new validation issues when code changes

Troubleshooting​

Node.js Version Issues​

If you encounter Node.js version warnings:

# Use Node Version Manager to install compatible version
nvm install 18
nvm use 18
npm install -g @stoplight/spectral-cli

Large OAS Files​

For large specifications, increase memory limit:

node --max-old-space-size=4096 $(which spectral) lint large-oas.json

Docker Integration​

Run Spectral in Docker for consistent environments:

docker run --rm -v $(pwd):/work stoplight/spectral lint /work/oas-register-15.json

Summary​

Using Spectral for OAS validation ensures:

  • ✅ OpenAPI specification compliance
  • ✅ Consistent API documentation quality
  • ✅ Early detection of specification issues
  • ✅ Automated quality checks in CI/CD
  • ✅ Better developer experience with generated SDKs

Regular validation helps maintain high-quality API documentation that accurately reflects your OpenRegister implementation.