Zuplo logo

Schema Validation with File Refs

Use the Request Validation policy with OpenAPI that references external files.

Prerequisite: You need a Zuplo account to run this example. Sign up for free

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

A production-ready API gateway with authentication, rate limiting, request validation, and size limits.

Idempotency Keys

Programmability

Idempotency keys prevent duplicate requests and cache responses.

Custom Rate Limiting

Programmability

Invoke the Rate Limit policy programatically and then modify the 429 response.

Custom Modules

Programmability

How to bundle custom node modules to use in your Zuplo project.