Validating Pathname
You can validate the pathname of a request using string schemas. The pathname is extracted from the request URL (e.g., "/api/users" or "/api/posts/123").
Using z.literal
The simplest way is to use Zod's z.literal():
import { requestSchema } from "@nicnocquee/zod-request";
import { z } from "zod";
export async function GET(request: Request) {
const validatedRequest = await requestSchema({
pathname: z.literal("/api/users"),
}).parseAsync(request);
const pathname = validatedRequest.pathname; // "/api/users"
}Using z.string()
You can use any string schema to validate the pathname:
import { requestSchema } from "@nicnocquee/zod-request";
import { z } from "zod";
export async function GET(request: Request) {
const validatedRequest = await requestSchema({
pathname: z.string(),
}).parseAsync(request);
const pathname = validatedRequest.pathname; // e.g., "/api/users"
}Using String Validation Methods
You can use Zod's string validation methods to validate pathnames:
import { requestSchema } from "@nicnocquee/zod-request";
import { z } from "zod";
export async function GET(request: Request) {
// Validate pathname contains "api"
const validatedRequest = await requestSchema({
pathname: z.string().includes("api"),
}).parseAsync(request);
const pathname = validatedRequest.pathname;
}Using Regular Expressions
You can use regex patterns to validate pathnames:
import { requestSchema } from "@nicnocquee/zod-request";
import { z } from "zod";
export async function GET(request: Request) {
// Validate pathname matches pattern for user IDs
const validatedRequest = await requestSchema({
pathname: z.string().regex(/^\/api\/users\/\d+$/),
}).parseAsync(request);
const pathname = validatedRequest.pathname;
}Pathname Validation with Other Validations
You can combine pathname validation with other request validations:
import {
requestSchema,
protocolSchema,
searchParamsSchema,
bodySchema,
headersSchema,
httpMethodSchema,
requestModeSchema,
} from "@nicnocquee/zod-request";
import { z } from "zod";
export async function POST(request: Request) {
const validatedRequest = await requestSchema({
pathname: z.literal("/api/users"),
protocol: protocolSchema("https"),
method: httpMethodSchema("POST"),
mode: requestModeSchema("cors"),
searchParams: searchParamsSchema(
z.object({
filter: z.string(),
})
),
body: bodySchema({
json: z.object({
name: z.string(),
}),
}),
headers: headersSchema(
z.object({
authorization: z.string(),
})
),
}).parseAsync(request);
const pathname = validatedRequest.pathname; // "/api/users"
const protocol = validatedRequest.protocol; // "https"
const method = validatedRequest.method; // "POST"
const mode = validatedRequest.mode; // "cors"
const filter = validatedRequest.searchParamsObject?.filter;
const name = validatedRequest.bodyObject?.name;
const auth = validatedRequest.headersObj?.authorization;
}Error Handling
If the request pathname doesn't match the schema, a validation error will be thrown:
import { requestSchema } from "@nicnocquee/zod-request";
import { z } from "zod";
export async function handler(request: Request) {
try {
const validatedRequest = await requestSchema({
pathname: z.literal("/api/users"),
}).parseAsync(request);
} catch (error) {
// Request pathname was not "/api/users"
// Handle error appropriately
}
}Pathname Extraction
The pathname is automatically extracted from the request URL. The pathname
does not include query parameters or hash fragments. For example, a URL like
https://example.com/api/users?page=1#section will have a pathname of
"/api/users" (without the query or hash).
import { requestSchema } from "@nicnocquee/zod-request";
import { z } from "zod";
// Request with "https://example.com/api/users?page=1" will have pathname "/api/users"
export async function handler(request: Request) {
const validatedRequest = await requestSchema({
pathname: z.literal("/api/users"), // Query params are not included
}).parseAsync(request);
const pathname = validatedRequest.pathname; // "/api/users" (without query)
}Common Use Cases
Validating API Endpoints
import { requestSchema } from "@nicnocquee/zod-request";
import { z } from "zod";
export async function apiHandler(request: Request) {
const validatedRequest = await requestSchema({
pathname: z.literal("/api/users"),
protocol: z.literal("https"),
}).parseAsync(request);
// Only HTTPS requests to "/api/users" are allowed
}Allowing Multiple Routes
import { requestSchema } from "@nicnocquee/zod-request";
import { z } from "zod";
export async function handler(request: Request) {
const validatedRequest = await requestSchema({
pathname: z.enum(["/api/users", "/api/posts", "/api/comments"]),
}).parseAsync(request);
// Allows requests to any of these routes
}Validating Dynamic Routes
import { requestSchema } from "@nicnocquee/zod-request";
import { z } from "zod";
export async function handler(request: Request) {
// Only allow routes matching the pattern /api/users/{id}
const validatedRequest = await requestSchema({
pathname: z.string().regex(/^\/api\/users\/\d+$/),
}).parseAsync(request);
// Matches: /api/users/123, /api/users/456
// Does not match: /api/users, /api/posts/123
}Validating Routes with Includes
import { requestSchema } from "@nicnocquee/zod-request";
import { z } from "zod";
export async function handler(request: Request) {
// Only allow API routes
const validatedRequest = await requestSchema({
pathname: z.string().includes("api"),
}).parseAsync(request);
// Matches: /api/users, /api/posts, /v1/api/users
}