Skip to main content

Documentation Index

Fetch the complete documentation index at: https://robintail-express-zod-api-69.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Middleware executes before endpoint handlers, providing authentication, context, and input validation. Middleware can be chained and composed.
import { Middleware } from "express-zod-api";
import { z } from "zod";

const authMiddleware = new Middleware({
  input: z.object({ token: z.string() }),
  handler: async ({ input, request }) => {
    const user = await validateToken(input.token);
    return { user };
  },
});

Configuration

input

Type: ZodObject Input validation schema for the middleware.

handler

Type: Handler<Input, Output, Context> Required: Yes Async function that returns context for endpoints.

security

Type: SecuritySchema Security requirements for OpenAPI documentation.
security: {
  and: [
    { type: "input", name: "key" },
    { type: "header", name: "token" },
  ],
}

Handler Return Value

The middleware handler must return an object that becomes part of the endpoint’s context:
handler: async ({ input }) => {
  const user = await getUser(input.userId);
  const permissions = await getPermissions(user);
  
  return { user, permissions }; // Available in ctx
}

Chaining Middleware

const factory = defaultEndpointsFactory
  .addMiddleware(authMiddleware)
  .addMiddleware({
    handler: async ({ ctx: { user } }) => {
      const settings = await getSettings(user.id);
      return { settings };
    },
  });

// Endpoints have ctx: { user, settings }

Security Declarations

Declare security requirements for documentation:
// API Key
security: { type: "input", name: "apiKey" }

// Bearer Token
security: { type: "header", name: "authorization" }

// OAuth2
security: {
  type: "oauth2",
  flows: {
    authorizationCode: {
      authorizationUrl: "https://auth.example.com/oauth/authorize",
      tokenUrl: "https://auth.example.com/oauth/token",
      scopes: { read: "Read access", write: "Write access" },
    },
  },
}

// Multiple requirements (AND)
security: {
  and: [
    { type: "input", name: "key" },
    { type: "header", name: "token" },
  ],
}

// Alternative requirements (OR)
security: {
  or: [
    { type: "header", name: "authorization" },
    { type: "input", name: "apiKey" },
  ],
}

Examples

Authentication Middleware

import createHttpError from "http-errors";

const authMiddleware = new Middleware({
  security: { type: "header", name: "authorization" },
  handler: async ({ request }) => {
    const token = request.headers.authorization?.replace("Bearer ", "");
    
    if (!token) {
      throw createHttpError(401, "Missing token");
    }
    
    const user = await verifyJWT(token);
    if (!user) {
      throw createHttpError(401, "Invalid token");
    }
    
    return { user };
  },
});

Rate Limiting Middleware

const rateLimitMiddleware = new Middleware({
  handler: async ({ request, logger }) => {
    const ip = request.ip;
    const count = await redis.incr(`rate:${ip}`);
    
    if (count === 1) {
      await redis.expire(`rate:${ip}`, 60);
    }
    
    if (count > 100) {
      logger.warn(`Rate limit exceeded for ${ip}`);
      throw createHttpError(429, "Too many requests");
    }
    
    return {};
  },
});

See Also

EndpointsFactory

Add middleware to factories

Authentication Guide

Complete authentication examples