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
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