Comprehensive request handling utilities for parsing query parameters, route parameters, request body, headers, and HTTP method validation.
Convert various input types to standard Request objects.
/**
* Convert input to a standard Request object
* @param input - Server request, URL, or string
* @param options - Optional request initialization options
* @returns Standard Request object
*/
function toRequest(input: ServerRequest | URL | string, options?: RequestInit): ServerRequest;Usage Examples:
import { toRequest } from "h3";
// Convert URL to Request
const request1 = toRequest("https://example.com/api");
// Convert with options
const request2 = toRequest("https://example.com/api", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ test: true })
});
// Use in handler
const handler = defineHandler((event) => {
const standardRequest = toRequest(event.req);
return { method: standardRequest.method };
});Parse and validate query parameters from request URLs.
/**
* Get parsed query parameters from request
* @param event - H3 event
* @returns Parsed query parameters object
*/
function getQuery<T = Record<string, string>>(event: HTTPEvent): T;
/**
* Get validated query parameters
* @param event - H3 event
* @param validate - Validation function or schema
* @returns Promise resolving to validated query parameters
*/
function getValidatedQuery<T>(
event: HTTPEvent,
validate: ((data: any) => T) | ValidationSchema<T>
): Promise<T>;Usage Examples:
import { getQuery, getValidatedQuery } from "h3";
// Basic query parsing
const handler = defineHandler((event) => {
const query = getQuery(event);
// URL: /search?q=hello&page=1
// query = { q: "hello", page: "1" }
return { query };
});
// Typed query parsing
const typedHandler = defineHandler((event) => {
const query = getQuery<{ q?: string; page?: string; limit?: string }>(event);
const page = parseInt(query.page || "1");
const limit = parseInt(query.limit || "10");
return { q: query.q, page, limit };
});
// Validated query with Zod
import { z } from "zod";
const validatedHandler = defineHandler(async (event) => {
const schema = z.object({
q: z.string().min(1),
page: z.string().transform(Number).default("1"),
limit: z.string().transform(Number).max(100).default("10")
});
const query = await getValidatedQuery(event, schema.parse);
return { query };
});Extract and validate parameters from route patterns.
/**
* Get all route parameters from matched route
* @param event - HTTP event
* @param opts - Options for parameter extraction
* @returns Object with all route parameters
*/
function getRouterParams(
event: HTTPEvent,
opts?: { decode?: boolean }
): Record<string, string>;
/**
* Get a single route parameter by name
* @param event - HTTP event
* @param name - Parameter name
* @param opts - Options for parameter extraction
* @returns Parameter value or undefined
*/
function getRouterParam(
event: HTTPEvent,
name: string,
opts?: { decode?: boolean }
): string | undefined;
/**
* Get validated route parameters
* @param event - H3 event
* @param validate - Validation function or schema
* @param opts - Options for parameter extraction
* @returns Promise resolving to validated parameters
*/
function getValidatedRouterParams<T>(
event: HTTPEvent,
validate: ((data: any) => T) | ValidationSchema<T>,
opts?: { decode?: boolean }
): Promise<T>;Usage Examples:
import { getRouterParam, getRouterParams, getValidatedRouterParams } from "h3";
// Single parameter
const userHandler = defineHandler((event) => {
const userId = getRouterParam(event, "id");
// Route: /users/:id
// URL: /users/123
// userId = "123"
return { userId };
});
// Multiple parameters
const nestedHandler = defineHandler((event) => {
const params = getRouterParams(event);
// Route: /posts/:postId/comments/:commentId
// URL: /posts/456/comments/789
// params = { postId: "456", commentId: "789" }
return { params };
});
// URL decoding
const decodedHandler = defineHandler((event) => {
const slug = getRouterParam(event, "slug", { decode: true });
// Route: /articles/:slug
// URL: /articles/hello%20world
// slug = "hello world"
return { slug };
});
// Validated parameters
const validatedHandler = defineHandler(async (event) => {
const params = await getValidatedRouterParams(
event,
(data) => ({
id: parseInt(data.id),
category: data.category
}),
{ decode: true }
);
return { params };
});Validate and assert HTTP methods.
/**
* Check if request method matches expected method(s)
* @param event - HTTP event
* @param expected - Expected method or array of methods
* @param allowHead - Whether to allow HEAD for GET requests
* @returns True if method matches
*/
function isMethod(
event: HTTPEvent,
expected: HTTPMethod | HTTPMethod[],
allowHead?: boolean
): boolean;
/**
* Assert that request method matches expected method(s)
* @param event - HTTP event
* @param expected - Expected method or array of methods
* @param allowHead - Whether to allow HEAD for GET requests
* @throws HTTPError if method doesn't match
*/
function assertMethod(
event: HTTPEvent,
expected: HTTPMethod | HTTPMethod[],
allowHead?: boolean
): void;Usage Examples:
import { isMethod, assertMethod } from "h3";
// Method checking
const handler = defineHandler((event) => {
if (isMethod(event, "POST")) {
return handlePost(event);
} else if (isMethod(event, ["GET", "HEAD"])) {
return handleGet(event);
} else {
throw HTTPError.status(405, "Method Not Allowed");
}
});
// Method assertion
const postOnlyHandler = defineHandler(async (event) => {
assertMethod(event, "POST");
const body = await readBody(event);
return { created: body };
});
// Multiple methods with HEAD support
const getHandler = defineHandler((event) => {
assertMethod(event, "GET", true); // Allows HEAD requests
return { data: "response data" };
});Read and validate request body content.
/**
* Read and parse request body
* @param event - H3 event
* @returns Promise resolving to parsed body or undefined
*/
function readBody<T = any>(event: HTTPEvent): Promise<T | undefined>;
/**
* Read and validate request body
* @param event - H3 event
* @param validate - Validation function or schema
* @returns Promise resolving to validated body
*/
function readValidatedBody<T>(
event: HTTPEvent,
validate: ((data: any) => T) | ValidationSchema<T>
): Promise<T>;Usage Examples:
import { readBody, readValidatedBody } from "h3";
// Basic body reading
const createHandler = defineHandler(async (event) => {
const body = await readBody(event);
// Automatic parsing based on content-type:
// - application/json -> parsed JSON
// - application/x-www-form-urlencoded -> parsed form data
// - text/* -> string
// - multipart/form-data -> FormData
return { received: body };
});
// Typed body reading
const typedHandler = defineHandler(async (event) => {
const body = await readBody<{ name: string; email: string }>(event);
return {
name: body?.name,
email: body?.email
};
});
// Validated body with schema
const validatedHandler = defineHandler(async (event) => {
const body = await readValidatedBody(event, (data) => {
if (!data || typeof data !== "object") {
throw new Error("Invalid body");
}
if (!data.name || typeof data.name !== "string") {
throw new Error("Name is required");
}
return data as { name: string; email?: string };
});
return { body };
});
// Zod validation
import { z } from "zod";
const zodHandler = defineHandler(async (event) => {
const schema = z.object({
name: z.string().min(1),
email: z.string().email(),
age: z.number().min(0)
});
const body = await readValidatedBody(event, schema.parse);
return { body };
});Extract URL, host, protocol, and IP information from requests.
/**
* Get the full request URL
* @param event - HTTP event
* @param opts - Options for URL construction
* @returns Complete URL object
*/
function getRequestURL(event: HTTPEvent, opts?: {
xForwardedHost?: boolean;
xForwardedProto?: boolean;
}): URL;
/**
* Get request host name
* @param event - HTTP event
* @param opts - Options for host detection
* @returns Host name string
*/
function getRequestHost(event: HTTPEvent, opts?: {
xForwardedHost?: boolean;
}): string;
/**
* Get request protocol (http/https)
* @param event - HTTP event
* @param opts - Options for protocol detection
* @returns Protocol string
*/
function getRequestProtocol(event: HTTPEvent, opts?: {
xForwardedProto?: boolean;
}): string;
/**
* Get client IP address
* @param event - HTTP event
* @param opts - Options for IP detection
* @returns IP address string or undefined
*/
function getRequestIP(event: HTTPEvent, opts?: {
xForwardedFor?: boolean;
}): string | undefined;Usage Examples:
import { getRequestURL, getRequestHost, getRequestProtocol, getRequestIP } from "h3";
// URL information
const urlHandler = defineHandler((event) => {
const url = getRequestURL(event);
return {
fullUrl: url.toString(),
pathname: url.pathname,
search: url.search,
host: url.host,
protocol: url.protocol
};
});
// Host with proxy support
const hostHandler = defineHandler((event) => {
const host = getRequestHost(event, { xForwardedHost: true });
const protocol = getRequestProtocol(event, { xForwardedProto: true });
return { host, protocol, baseUrl: `${protocol}://${host}` };
});
// Client IP detection
const ipHandler = defineHandler((event) => {
const ip = getRequestIP(event, { xForwardedFor: true });
return { clientIp: ip };
});
// Complete request info
const infoHandler = defineHandler((event) => {
const url = getRequestURL(event, {
xForwardedHost: true,
xForwardedProto: true
});
const ip = getRequestIP(event, { xForwardedFor: true });
return {
method: event.req.method,
url: url.toString(),
ip,
userAgent: event.req.headers.get("user-agent"),
timestamp: new Date().toISOString()
};
});/**
* HTTP method union type
*/
type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE';
/**
* Validation schema type
*/
type ValidationSchema<T> = (data: any) => T;
/**
* Request URL options
*/
interface RequestURLOptions {
/**
* Use X-Forwarded-Host header
*/
xForwardedHost?: boolean;
/**
* Use X-Forwarded-Proto header
*/
xForwardedProto?: boolean;
}Handle custom content types and parsing logic.
// Example custom parser pattern
const customHandler = defineHandler(async (event) => {
const contentType = event.req.headers.get("content-type");
if (contentType?.includes("application/xml")) {
const xmlText = await event.req.text();
const parsed = parseXML(xmlText);
return { xml: parsed };
}
const body = await readBody(event);
return { body };
});Create reusable validation middleware.
// Example validation middleware
function createValidationMiddleware<T>(schema: (data: any) => T) {
return defineMiddleware(async (event) => {
if (isMethod(event, ["POST", "PUT", "PATCH"])) {
const body = await readValidatedBody(event, schema);
event.context.validatedBody = body;
}
});
}Usage Examples:
// Use validation middleware
const userValidation = createValidationMiddleware((data) => {
if (!data?.name) throw new Error("Name required");
if (!data?.email) throw new Error("Email required");
return data as { name: string; email: string };
});
app.use("/api/users", userValidation);
app.post("/api/users", defineHandler((event) => {
const validatedData = event.context.validatedBody;
return createUser(validatedData);
}));