Zuplo

Schema Validation with File Refs

Validate requests against JSON schemas stored in separate files.

Schema Validation with File References

This example demonstrates how to use the Request Validation policy with OpenAPI schemas stored in external files using $ref. This pattern keeps your route definitions clean and allows you to reuse schemas across multiple endpoints.

Prerequisites

Working with this Example

Locally

Working locally is the best way to explore and understand the code for this example. You can get a local version by using the Zuplo CLI:

Terminalbash
npx create-zuplo-api@latest --example schema-validation-file-ref

Then, in the project directory run the following commands:

Terminalbash
npm install
npm run dev

Deploy this example to Zuplo

It is also possible to deploy this example directly to your Zuplo account and work with it via the Zuplo Portal. You can do this by clicking the Deploy to Zuplo button anywhere on this page.

How It Works

External Schema References

Instead of defining schemas inline in your OpenAPI document, you can reference external JSON Schema files:

JSONjson
{
  "requestBody": {
    "content": {
      "application/json": {
        "schema": {
          "$ref": "../schemas/insert-todo-object.json"
        }
      }
    }
  }
}

Request Validation Policy

The request-validation-inbound policy automatically validates incoming requests against the referenced schemas:

JSONjson
{
  "handler": {
    "export": "RequestValidationInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "validateBody": "reject-and-log",
      "validatePathParameters": "none",
      "validateQueryParameters": "none"
    }
  }
}

When validation fails, the policy returns a 400 Bad Request with details about what failed.

Project Structure

text
├── config/
│   ├── policies.json        # Policy configurations
│   └── routes.oas.json      # Route definitions with $ref to schemas
└── schemas/
    ├── insert-todo-object.json      # Schema for creating todos
    ├── todo-object.json             # Schema for todo response
    └── schema-validation-error.json # Schema for validation errors

Schema Example

The insert-todo-object.json schema defines the required fields for creating a todo:

JSONjson
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["userId", "title", "completed"],
  "additionalProperties": false,
  "properties": {
    "userId": { "type": "integer" },
    "title": { "type": "string" },
    "completed": { "type": "boolean" }
  }
}

Testing the Example

Valid Request

Terminalbash
curl -X POST http://localhost:9000/v1/todos \
  -H "Content-Type: application/json" \
  -d '{"userId": 1, "title": "Wash the dishes", "completed": false}'

Invalid Request (missing required field)

Terminalbash
curl -X POST http://localhost:9000/v1/todos \
  -H "Content-Type: application/json" \
  -d '{"title": "Wash the dishes"}'

This returns a 400 error with validation details:

JSONjson
{
  "type": "https://httpproblems.com/http-status/400",
  "title": "Bad Request",
  "status": 400,
  "detail": "Incoming request body did not pass schema validation",
  "errors": [
    {
      "path": "",
      "message": "must have required property 'userId'"
    }
  ]
}

Validation Options

OptionValuesDescription
validateBodyreject-and-log, log-only, noneHow to handle body validation failures
validatePathParametersreject-and-log, log-only, noneHow to handle path parameter validation
validateQueryParametersreject-and-log, log-only, noneHow to handle query parameter validation

Common Customizations

  • Add more schemas: Create new .json files in the schemas/ directory and reference them with $ref
  • Reuse schemas: Reference the same schema file from multiple endpoints
  • Nested schemas: Use $ref within schemas to reference other schemas
  • Change validation behavior: Set to log-only during development to see validation errors without rejecting requests

Learn More

Related Examples

Explore more examples in this category

Starter

Basic API Gateway

Authentication

Protect your backend API with authentication, rate limiting, and request validation.

Circuit Breaker

Programmability

Protect your backend from cascading failures by automatically blocking traffic when error rates exceed a threshold.

Custom Rate Limiting

Programmability

Customize the error response users see when they hit your API rate limits.

Custom Modules

Programmability

Use npm packages and third-party libraries in your Zuplo handlers and policies.