Minimal H(TTP) framework built for high performance and portability across multiple JavaScript runtimes.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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);
}));