Skip to main content

Introduction

The OpenAPI Validation package validates incoming request bodies against your existing OpenAPI specification — no extra schema definitions needed. If you already document your API with @OasRequestBody decorators, this package reuses those schemas at runtime to ensure that every request matches the contract.

It uses Ajv under the hood for fast, standards-compliant JSON Schema validation and supports both OpenAPI v3.1 and v3.2.

Install dependencies

Install the package along with its peer dependencies:

npm install ajv ajv-formats @inversifyjs/open-api-validation

Quick Start

Here's a complete example showing OpenAPI-driven body validation:

import { Controller, Post } from '@inversifyjs/http-core';
import { InversifyExpressHttpAdapter } from '@inversifyjs/http-express';
import { OasRequestBody, SwaggerUiProvider } from '@inversifyjs/http-open-api';
import { InversifyValidationErrorFilter } from '@inversifyjs/http-validation';
import { type OpenApi3Dot1Object } from '@inversifyjs/open-api-types/v3Dot1';
import { ValidatedBody } from '@inversifyjs/open-api-validation';
import { OpenApiValidationPipe } from '@inversifyjs/open-api-validation/v3Dot1';
import { Container } from 'inversify';

const container: Container = new Container();

// Define a base OpenAPI document
const openApiObject: OpenApi3Dot1Object = {
info: { title: 'My API', version: '1.0.0' },
openapi: '3.1.1',
};

// Create the SwaggerUiProvider
const swaggerProvider: SwaggerUiProvider = new SwaggerUiProvider({
api: {
openApiObject,
path: '/docs',
},
});

interface User {
email: string;
name: string;
}

@Controller('/users')
export class UserController {
@OasRequestBody({
content: {
'application/json': {
schema: {
additionalProperties: false,
properties: {
email: { format: 'email', type: 'string' },
name: { minLength: 1, type: 'string' },
},
required: ['name', 'email'],
type: 'object',
},
},
},
})
@Post('/')
public createUser(@ValidatedBody() user: User): string {
return `Created user: ${user.name}`;
}
}

// Register bindings
container.bind(InversifyValidationErrorFilter).toSelf().inSingletonScope();
container.bind(UserController).toSelf().inSingletonScope();

// Populate the OpenAPI spec from controller metadata
swaggerProvider.provide(container);

// Create HTTP adapter
const adapter: InversifyExpressHttpAdapter = new InversifyExpressHttpAdapter(
container,
);

// Register global validation pipe using the populated OpenAPI spec
adapter.useGlobalPipe(new OpenApiValidationPipe(swaggerProvider.openApiObject));
adapter.useGlobalFilters(InversifyValidationErrorFilter);

This example:

  1. Defines an OpenAPI request body schema using @OasRequestBody on the controller method.
  2. Uses @ValidatedBody() to extract and mark the body parameter for validation.
  3. Uses SwaggerUiProvider to populate the OpenAPI spec from controller metadata.
  4. Creates an OpenApiValidationPipe from the populated spec and registers it globally.

When a request arrives, the pipe validates the body against the OpenAPI schema. Invalid requests are rejected with an InversifyValidationError, which the InversifyValidationErrorFilter converts into a 400 Bad Request response.

How It Works

The validation flow:

  1. Schema discoverySwaggerUiProvider.provide(container) reads all @OasRequestBody decorators and populates the OpenAPI document with paths and schemas.
  2. Pipe initializationOpenApiValidationPipe receives the populated OpenAPI document and lazily initializes an Ajv instance with the full spec on first use.
  3. Request validation — For each request, the pipe:
    • Checks if the parameter is decorated with @ValidatedBody().
    • Resolves the content type (extracted from the request by @ValidatedBody(), or falls back to a single declared type).
    • Locates the matching schema using JSON pointer navigation.
    • Validates the body against the schema using Ajv.
  4. Error handling — Validation failures throw InversifyValidationError with detailed error information.

OpenAPI Version Support

The package supports both OpenAPI v3.1 and v3.2 through subpath exports:

// ValidatedBody decorator (version-agnostic)
import { ValidatedBody } from '@inversifyjs/open-api-validation';

// OpenAPI v3.1 pipe
import { OpenApiValidationPipe } from '@inversifyjs/open-api-validation/v3Dot1';

// OpenAPI v3.2 pipe
import { OpenApiValidationPipe } from '@inversifyjs/open-api-validation/v3Dot2';

ValidatedBody is shared across versions — import it from the root. The OpenApiValidationPipe is version-specific — import it from the matching subpath. Use the matching OpenAPI decorators and types from @inversifyjs/http-open-api or @inversifyjs/http-open-api/v3Dot2.