Overview

Enforce your API contract using an openapi.yaml file. Provides both documentation and runtime request/response validation.

Features

  • Contract-first development setup
  • Runtime request and response validation
  • Static openapi.yaml serving via Swagger UI
  • Clear validation error handling

Installation

npx hanma add docs/openapi

Dependencies

express-openapi-validator, swagger-ui-express, js-yaml

Code

import path from 'path';
import express, { Express } from 'express';
import * as OpenApiValidator from 'express-openapi-validator';
import swaggerUi from 'swagger-ui-express';
import yaml from 'js-yaml';
import fs from 'fs';

/**
 * Setup OpenAPI validation and documentation
 * This follows a contract-first approach where you define your API in openapi.yaml
 * 
 * @param app Express application
 */
export const setupOpenApi = (app: Express) => {
  const specPath = path.join(process.cwd(), 'docs/openapi.yaml');
  
  if (!fs.existsSync(specPath)) {
    console.warn(`[WARN] OpenAPI spec not found at ${specPath}. Documentation and validation disabled.`);
    return;
  }

  const spec = yaml.load(fs.readFileSync(specPath, 'utf8')) as Record<string, any>;

  // 1. Serve Swagger UI
  app.use('/docs', swaggerUi.serve, swaggerUi.setup(spec));

  // 2. Install OpenAPI Validator
  app.use(
    OpenApiValidator.middleware({
      apiSpec: specPath,
      validateRequests: true,
      validateResponses: true,
    })
  );

  // 3. Error handler for validation errors
  app.use((err: any, req: express.Request, res: express.Response, next: express.NextFunction) => {
    if (err.status) {
      res.status(err.status).json({
        message: err.message,
        errors: err.errors,
      });
    } else {
      next(err);
    }
  });

  console.log('[OK] OpenAPI documentation and validation enabled');
};

/**
 * Example usage in index.ts:
 * 
 * import express from 'express';
 * import { setupOpenApi } from './libs/docs/openapi';
 * 
 * const app = express();
 * app.use(express.json());
 * 
 * // Setup OpenAPI (Contract-first)
 * setupOpenApi(app);
 * 
 * // Your routes here
 * // They will be automatically validated against openapi.yaml
 * 
 * app.listen(3000);
 */

---
# docs/openapi.yaml
openapi: 3.0.0
info:
  title: Express API
  version: 1.0.0
  description: API documentation and contract
paths:
  /health:
    get:
      summary: Health check
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: ok

Usage

import { setupOpenApi } from './libs/docs/openapi';

const app = express();
setupOpenApi(app);

Dependencies

Frequently Asked Questions

How do I install OpenAPI Validator?
Run the following command: npx hanma add docs/openapi
What dependencies are required?
This snippet requires: express-openapi-validator, swagger-ui-express, js-yaml. Make sure to install them before using the snippet.
How do I use this snippet?
Copy the code and paste it into your project. The snippet will be saved to libs/docs/openapi.ts.
Can I customize this snippet?
Yes! All snippets are copy-paste code that you own. Feel free to modify them to fit your needs.
Does this work with other frameworks?
This snippet is designed for the specific framework. Check the other framework pages for equivalent implementations.