openapi-contract

OpenAPI Contract Validation - Quick Reference

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "openapi-contract" with this command: npx skills add claude-dev-suite/claude-dev-suite/claude-dev-suite-claude-dev-suite-openapi-contract

OpenAPI Contract Validation - Quick Reference

When NOT to Use This Skill

  • GraphQL APIs - Use graphql-contract skill

  • Authentication flows - Use auth-flow-validation skill

  • API versioning strategy - Use api-versioning skill

  • Type generation setup - Use type-generation skill

Deep Knowledge: Use mcp__api-explorer__get_api_endpoint_details for specific endpoint validation.

Contract Validation Overview

┌─────────────────────────────────────────────────────────────┐ │ CONTRACT VALIDATION │ ├─────────────────────────────────────────────────────────────┤ │ │ │ Frontend Code OpenAPI Spec Backend │ │ ┌──────────────┐ ┌────────────┐ ┌──────────────┐ │ │ │ fetch('/api/ │ ←──→ │ paths: │ ←──→│ @Controller │ │ │ │ users') │ │ /users: │ │ @GetMapping │ │ │ │ │ │ get: │ │ │ │ │ │ type User { │ ←──→ │ schemas: │ ←──→│ class UserDto│ │ │ │ id: number │ │ User: │ │ Long id │ │ │ │ } │ │ id:int │ │ │ │ │ └──────────────┘ └────────────┘ └──────────────┘ │ │ │ │ MUST MATCH SOURCE OF MUST MATCH │ │ TRUTH │ └─────────────────────────────────────────────────────────────┘

Common Discrepancy Types

  1. Path Mismatch

OpenAPI Spec

paths: /users/{userId}: # Backend path get: ...

Frontend Code

fetch('/api/users/${id}') # Frontend uses different path!

Detection:

Find API calls in frontend

grep -r "fetch|axios|http." src/

Compare with OpenAPI paths

Use api-explorer to list paths

Fix: Update frontend to use correct path or configure base URL.

  1. Type Mismatch

OpenAPI Spec

components: schemas: User: properties: age: type: string # Backend uses string

Frontend Code

interface User { age: number; # Frontend expects number! }

Detection:

// Frontend type interface CreateUserDto { age: number; // MISMATCH }

// Should be interface CreateUserDto { age: string; // Match OpenAPI spec }

  1. Required Field Missing

OpenAPI Spec

components: schemas: CreateUserRequest: required: - email - name - role # Required! properties: email: { type: string } name: { type: string } role: { type: string }

Frontend Code

const payload = { email: user.email, name: user.name, // role is missing! <-- Will fail validation };

  1. Response Structure Mismatch

OpenAPI Spec - Paginated response

paths: /users: get: responses: 200: content: application/json: schema: type: object properties: data: type: array items: $ref: '#/components/schemas/User' meta: $ref: '#/components/schemas/PaginationMeta'

Frontend Code - Expects array directly

const users: User[] = await response.json(); // WRONG! // Should be const { data, meta } = await response.json(); const users: User[] = data;

Validation Checklist

Per-Endpoint Validation

Check Frontend Backend (OpenAPI) Status

Path /api/users

/users

MISMATCH

Method POST POST OK

Content-Type application/json application/json OK

Request Body matches schema CreateUserRequest CHECK

Response Type matches schema User CHECK

Status Codes handles 400, 401 200, 400, 401, 500 PARTIAL

Request Body Validation

// OpenAPI Schema interface CreateUserRequest { email: string; // required name: string; // required age?: number; // optional role: UserRole; // required, enum }

// Validate frontend matches interface FrontendPayload { email: string; // OK - required name: string; // OK - required age?: number; // OK - optional role: 'admin' | 'user'; // CHECK - enum values match? }

Response Handling Validation

// OpenAPI Response interface ApiResponse<T> { data: T; meta?: { page: number; total: number; }; error?: { code: string; message: string; }; }

// Frontend should handle all cases async function fetchUsers(): Promise<User[]> { const response = await fetch('/api/users');

if (!response.ok) { const error = await response.json(); throw new ApiError(error.error.code, error.error.message); }

const result: ApiResponse<User[]> = await response.json(); return result.data; }

Contract-First Development

  1. Define OpenAPI Spec First

openapi.yaml

openapi: 3.0.3 info: title: User API version: 1.0.0

paths: /users: post: operationId: createUser requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateUserRequest' responses: '201': description: User created content: application/json: schema: $ref: '#/components/schemas/User'

components: schemas: CreateUserRequest: type: object required: [email, name] properties: email: type: string format: email name: type: string minLength: 2 maxLength: 100

User:
  type: object
  properties:
    id:
      type: string
      format: uuid
    email:
      type: string
    name:
      type: string
    createdAt:
      type: string
      format: date-time

2. Generate Types for Both Ends

Frontend (TypeScript)

npx openapi-typescript openapi.yaml -o src/api/types.ts

Backend (Java/Spring)

npx @openapitools/openapi-generator-cli generate
-i openapi.yaml
-g spring
-o generated/

  1. Implement Against Generated Types

// Frontend - uses generated types import type { CreateUserRequest, User } from './api/types';

async function createUser(data: CreateUserRequest): Promise<User> { const response = await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); return response.json(); }

// Backend - uses generated DTOs @PostMapping("/users") public ResponseEntity<User> createUser( @Valid @RequestBody CreateUserRequest request) { // Implementation uses generated types }

MCP api-explorer Usage

Efficient Validation Queries

// 1. Search for endpoint await mcp__api_explorer__search_api({ query: "users", searchIn: ["paths"], limit: 10 });

// 2. Get specific endpoint details await mcp__api_explorer__get_api_endpoint_details({ path: "/users", method: "POST" });

// 3. Get request/response schemas await mcp__api_explorer__get_api_models({ model: "CreateUserRequest", compact: true });

Avoid Token Waste

// DON'T - Loads entire spec await mcp__api_explorer__get_api_schema({ format: "full" });

// DO - Query specific endpoints await mcp__api_explorer__get_api_endpoint_details({ path: "/users/{id}", method: "GET" });

Automated Contract Testing

Prism (Mock Server)

Start mock server from OpenAPI spec

npx @stoplight/prism-cli mock openapi.yaml

Run frontend tests against mock

npm test -- --api-url=http://localhost:4010

Schemathesis (API Fuzzing)

Test backend against OpenAPI spec

schemathesis run openapi.yaml --base-url=http://localhost:8080

Validate all endpoints

schemathesis run openapi.yaml
--checks all
--validate-schema

Dredd (Contract Testing)

Test implementation matches spec

dredd openapi.yaml http://localhost:8080

CI/CD Integration

GitHub Actions

name: Contract Validation on: [push, pull_request]

jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4

  - name: Validate OpenAPI spec
    run: npx @redocly/cli lint openapi.yaml

  - name: Generate types
    run: npx openapi-typescript openapi.yaml -o src/api/types.ts

  - name: Check types unchanged
    run: git diff --exit-code src/api/types.ts

  - name: Run contract tests
    run: npm run test:contract

Anti-Patterns

Anti-Pattern Why It's Bad Correct Approach

Manual type sync Drift over time Generate from spec

Ignoring OpenAPI spec No source of truth Contract-first development

Hardcoded URLs Environment issues Configure base URL

No validation in CI Breaks discovered late Automated contract tests

Any types for API No type safety Generate proper types

Quick Troubleshooting

Issue Likely Cause Solution

Types out of sync Manual updates Regenerate from spec

404 errors Path mismatch Check OpenAPI paths

400 Bad Request Missing required field Validate against schema

Unexpected response Response structure changed Update frontend types

CORS errors Backend config Check allowed origins

Related Skills

  • Type Generation

  • Auth Flow Validation

  • API Versioning

  • Error Contract

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

cron-scheduling

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

token-optimization

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

webrtc

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

react-19

No summary provided by upstream source.

Repository SourceNeeds Review