or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-features.mdcore-framework.mderror-handling.mdevent-handling.mdhandlers-middleware.mdindex.mdrequest-processing.mdresponse-handling.mdruntime-adapters.mdweb-utilities.md
tile.json

request-processing.mddocs/

Request Processing

Comprehensive request handling utilities for parsing query parameters, route parameters, request body, headers, and HTTP method validation.

Capabilities

Request Conversion

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 };
});

Query Parameter Handling

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 };
});

Route Parameter Handling

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 };
});

HTTP Method Handling

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" };
});

Request Body Handling

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 };
});

Request URL and Host Information

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()
  };
});

Utility Types

Request Processing Types

/**
 * 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;
}

Advanced Request Processing

Custom Body Parsers

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 };
});

Request Validation Middleware

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);
}));