yatta/api
File-based routing, request context, and validation.
15 exported symbols and 66 members, read from src/types/api.ts.
Construct
createAPI
functionFactory creating a typed router instance.
createAPI<Path extends string>(path?: Path): API<ExtractRouteParams<Path>>- path
- Optional route path pattern to infer typed parameters.
Returns A configured `API` instance.
// 1. Unparameterized routerconst api = createAPI();api.get((ctx) => API.json({ ok: true })); // 2. Typed parameterized routerconst userApi = createAPI("/users/[id]");userApi.get((ctx) => { // ctx.params.id is statically typed as string return API.json({ userId: ctx.params.id });});routeRequest
async functionDispatches an incoming HTTP `Request` through Bun's FileSystemRouter to matching backend route files.
routeRequest(req: Request): Promise<Response>- req
- Incoming HTTP Request.
Returns Response produced by the matched route handler or 404/500 response.
API
classLightweight, high-performance HTTP API router and middleware engine.
class APIconst api = createAPI(); api.use(async (ctx, next) => { console.log(`${ctx.req.method} ${ctx.url.pathname}`); return await next();}); api.get(async (ctx) => { return API.json({ status: "healthy" });}); export default api;38 members
routespropertyroutes:subRoutespropertysubRoutes: Array<{ method: Method; path: string; handler: Handler<any>; }>middlewareStackpropertymiddlewareStack: Middleware<TParams>[]errorHandlerpropertyerrorHandler?: ErrorHandler<TParams>corsOptionspropertycorsOptions?: CorsOptionsgetget(handler: Handler<TParams>): thisRegisters a GET route handler for the root endpoint of this route module.
- handler
- Handler function processing the request.
getget(path: string, handler: Handler<any>): thisRegisters a GET route handler for an explicit sub-path.
- path
- Sub-path string (e.g. `"/details"`).
- handler
- Handler function processing the request.
getget(pathOrHandler: string | Handler<TParams>, maybeHandler?: Handler<any>): thispostpost(handler: Handler<TParams>): thisRegisters a POST route handler for the root endpoint.
- handler
- Handler function processing the request.
postpost(path: string, handler: Handler<any>): thisRegisters a POST route handler for an explicit sub-path.
- path
- Sub-path string (e.g. `"/checkout"`).
- handler
- Handler function processing the request.
postpost(pathOrHandler: string | Handler<TParams>, maybeHandler?: Handler<any>): thisputput(handler: Handler<TParams>): thisRegisters a PUT route handler for the root endpoint.
- handler
- Handler function processing the request.
putput(path: string, handler: Handler<any>): thisRegisters a PUT route handler for an explicit sub-path.
- path
- Sub-path string.
- handler
- Handler function processing the request.
putput(pathOrHandler: string | Handler<TParams>, maybeHandler?: Handler<any>): thispatchpatch(handler: Handler<TParams>): thisRegisters a PATCH route handler for the root endpoint.
- handler
- Handler function processing the request.
patchpatch(path: string, handler: Handler<any>): thisRegisters a PATCH route handler for an explicit sub-path.
- path
- Sub-path string.
- handler
- Handler function processing the request.
patchpatch(pathOrHandler: string | Handler<TParams>, maybeHandler?: Handler<any>): thisdeletedelete(handler: Handler<TParams>): thisRegisters a DELETE route handler for the root endpoint.
- handler
- Handler function processing the request.
deletedelete(path: string, handler: Handler<any>): thisRegisters a DELETE route handler for an explicit sub-path.
- path
- Sub-path string.
- handler
- Handler function processing the request.
deletedelete(pathOrHandler: string | Handler<TParams>, maybeHandler?: Handler<any>): thisheadhead(handler: Handler<TParams>): thisRegisters a HEAD route handler for the root endpoint.
- handler
- Handler function processing the request.
headhead(path: string, handler: Handler<any>): thisRegisters a HEAD route handler for an explicit sub-path.
- path
- Sub-path string.
- handler
- Handler function processing the request.
headhead(pathOrHandler: string | Handler<TParams>, maybeHandler?: Handler<any>): thisoptionsoptions(handler: Handler<TParams>): thisRegisters an OPTIONS route handler for the root endpoint.
- handler
- Handler function processing the request.
optionsoptions(path: string, handler: Handler<any>): thisRegisters an OPTIONS route handler for an explicit sub-path.
- path
- Sub-path string.
- handler
- Handler function processing the request.
optionsoptions(pathOrHandler: string | Handler<TParams>, maybeHandler?: Handler<any>): thisuseuse(middleware: Middleware<TParams>): thisAttaches an onion-style middleware to the API execution pipeline.
- middleware
- Middleware function receiving `ctx` and `next()`.
Returns Current API instance for fluent chaining.
tsts api.use(async (ctx, next) => { const token = ctx.header("Authorization"); if (!token) throw new HttpError(401, "Missing token"); return await next();});onErroronError(handler: ErrorHandler<TParams>): thisRegisters a custom centralized error handler for this API instance.
- handler
- Error handler function.
Returns Current API instance for fluent chaining.
tsts api.onError((err, ctx) => { if (err instanceof ValidationError) { return API.json({ errors: err.details }, { status: 400 }); } return API.json({ error: "Internal Error" }, { status: 500 });});corscors(options?: CorsOptions): thisEnables CORS headers on all route responses and automatically handles OPTIONS preflights.
- options
- Configuration for allowed origins, headers, methods, credentials, and maxAge.
Returns Current API instance for fluent chaining.
tsts api.cors({ origin: "https://myfrontend.com", credentials: true, methods: ["GET", "POST", "DELETE"],});jsonjson<T>(data: T, init?: ResponseInit): ResponseCreates a JSON HTTP `Response` with `Content-Type: application/json; charset=utf-8`.
- data
- The JavaScript value or object to JSON-encode.
- init
- Optional response initialization options (status, headers, etc.).
Returns Standard `Response` object.
tsts return API.json({ success: true, count: 5 }, { status: 200 });texttext(data: string, init?: ResponseInit): ResponseCreates a plain text HTTP `Response` with `Content-Type: text/plain; charset=utf-8`.
- data
- Text string content.
- init
- Optional response initialization options.
Returns Standard `Response` object.
tsts return API.text("OK", { status: 200 });streamstream(body: ReadableStream, init?: ResponseInit): ResponseCreates a streaming HTTP `Response` from a `ReadableStream`.
- body
- The `ReadableStream` providing streaming data chunks.
- init
- Optional response initialization options (headers, status).
Returns Standard streaming `Response`.
tsts return API.stream(stream, { headers: { "Content-Type": "text/event-stream" }});cookiecookie(name: string, value: string, options?: CookieOptions): stringFormats a name-value pair into a standard `Set-Cookie` header value string.
- name
- Cookie name.
- value
- Cookie string value.
- options
- Cookie options (maxAge, path, domain, httpOnly, secure, sameSite).
Returns Formatted cookie header string.
tsts const cookieStr = API.cookie("auth_token", token, { httpOnly: true, secure: true, maxAge: 3600, sameSite: "Lax"});withCookieswithCookies(response: Response, cookies: string[]): ResponseAttaches one or more `Set-Cookie` header strings to an existing `Response`.
- response
- Original `Response` object.
- cookies
- Array of formatted cookie strings (e.g. from `API.cookie()`).
Returns New `Response` containing the attached `Set-Cookie` headers.
tsts const cookie = API.cookie("session", id, { httpOnly: true });return API.withCookies(API.json({ ok: true }), [cookie]);applyCorsapplyCors(response: Response, req: Request): ResponsedispatchErrordispatchError(error: unknown, ctx: Context<TParams>): Promise<Response>handlehandle(req: Request, params: TParams, basePath?: string): Promise<Response>Processes an incoming HTTP `Request`, executes middleware pipeline, matches route handlers,
- req
- The raw incoming HTTP Request.
- params
- Extracted path parameters.
- basePath
- Optional base path prefix if mounted as a sub-router.
Returns Promise resolving to the final HTTP `Response`.
runMiddlewarerunMiddleware(ctx: Context<TParams>, handler: Handler<TParams>): Promise<Response>
Context
classEncapsulates the incoming HTTP request context for route handlers and middleware.
class Contextapi.get(async (ctx) => { const query = ctx.query(); const userId = ctx.params.id; const authUser = ctx.state.user; return API.json({ query, userId, authUser });});13 members
reqpropertyreq: RequestThe native web-standard object.
paramspropertyparams: TParamsStrongly-typed route parameters extracted from the URL path.
urlpropertyurl: URLThe parsed of the current request.
statepropertystate: Record<string, unknown>Mutable dictionary for middleware to share request-scoped data
cachedCookiespropertycachedCookies?: Record<string, string>rawBodyParsedpropertyrawBodyParsed:rawBodyDatapropertyrawBodyData: unknownrawFormDatapropertyrawFormData?: FormDataqueryquery(): Record<string, string>Returns all query parameters as a key-value dictionary.
tsts // GET /search?q=bun&limit=10const { q, limit } = ctx.query();jsonjson<T = unknown>(schema?: Validator<T>): Promise<T>Parse and optionally validate the JSON request body.
- schema
- Optional schema validator (Zod, Valibot, ArkType) with a `.parse()` method.
Returns The parsed and validated body.
tsts // Without schema:const body = await ctx.json<{ name: string }>(); // With Zod schema:import { z } from "zod";const schema = z.object({ email: z.string().email(), age: z.number().min(18) });const data = await ctx.json(schema);formDataformData<T = FormData>(schema?: Validator<T>): Promise<T>Parse and optionally validate `multipart/form-data` or `application/x-www-form-urlencoded`.
- schema
- Optional schema validator with a `.parse()` method.
Returns Parsed `FormData` or validated output.
tsts const form = await ctx.formData();const avatarFile = form.get("avatar") as File;cookiescookies(): Record<string, string>Parses and decodes the incoming `Cookie` header into a key-value dictionary.
Returns Record of cookie names and their decoded values.
tsts const { session_token } = ctx.cookies();headerheader(name: string): string | nullRetrieves an incoming HTTP request header value by case-insensitive name.
- name
- Header name (e.g. `"authorization"`, `"user-agent"`).
Returns Header value string or `null` if not present.
tsts const authHeader = ctx.header("Authorization");
HttpError
classThrown to immediately abort handler execution with an explicit HTTP status code.
class HttpError extends Errorif (!user) { throw new HttpError(404, "User not found", { userId });}2 members
statuspropertystatus: numberHTTP response status code (e.g. 400, 401, 403, 404, 500).
detailspropertydetails?: unknownOptional arbitrary metadata or validation issues attached to the error.
ValidationError
classThrown when request body or form parsing/validation fails (HTTP 400 Bad Request).
class ValidationError extends HttpError1 member
causepropertycause: unknownThe underlying parser or validator error that caused the validation failure.
Types
CookieOptions
interfaceConfiguration options for generating `Set-Cookie` HTTP response headers.
interface CookieOptions6 members
maxAgepropertymaxAge?: numberMax-Age in seconds determining how long the client should store the cookie.
pathpropertypath?: stringThe URL path that must exist in the requested URL for the cookie to be sent.
domainpropertydomain?: stringThe host/domain to which the cookie will be sent.
httpOnlypropertyhttpOnly?: booleanForbids client-side JavaScript access via `Document.cookie` to prevent XSS theft.
securepropertysecure?: booleanEnsures the cookie is only transmitted over secure HTTPS connections.
sameSitepropertysameSite?: "Strict" | "Lax" | "None"Controls whether the cookie is sent with cross-site requests to mitigate CSRF attacks.
CorsOptions
interfaceConfiguration options for Cross-Origin Resource Sharing (CORS).
interface CorsOptions5 members
originpropertyorigin?: stringAllowed origin header value (e.g. `"https://example.com"` or `"*"`).
methodspropertymethods?: Method[]List of allowed HTTP methods for CORS requests.
headerspropertyheaders?: string[]List of allowed request headers (e.g. `["Content-Type", "Authorization"]`).
credentialspropertycredentials?: booleanWhether to include `Access-Control-Allow-Credentials: true` to permit cookies/auth tokens.
maxAgepropertymaxAge?: numberMaximum duration in seconds that preflight OPTIONS results can be cached by the browser.
Validator
interfaceSchema validator interface compatible with Zod, Valibot, ArkType, or custom parsers.
interface Validator<T>import { z } from "zod";const userSchema: Validator<{ name: string }> = z.object({ name: z.string() });const user = await ctx.json(userSchema);1 member
parseparse(data: unknown): TValidates and transforms the incoming data, throwing an error if validation fails.
- data
- Raw unvalidated data.
Returns Typed and sanitized value.
ErrorHandler
typeCentralized error handler invoked when an uncaught error or is thrown.
type ErrorHandler<TParams extends RouteParams = RouteParams> = (error: unknown, ctx: Context<TParams>) => Response | Promise<Response>- error
- The thrown error or exception.
- ctx
- The typed request context.
Returns A web-standard `Response` formatted for the client.
api.onError((err, ctx) => { console.error("Unhandled route error:", err); return API.json({ error: "Something went wrong" }, { status: 500 });});ExtractRouteParams
typeInfers typed route parameter dictionary from a path literal string at compile time.
type ExtractRouteParams<Path extends string> = Path extends `${infer _Start}[${infer Param}]${infer Rest}` ? { [K in CleanParam<Param> | keyof ExtractRouteParams<Rest>]: string; } : {}type Params = ExtractRouteParams<"/orgs/[orgId]/teams/[teamId]">;// => { orgId: string; teamId: string }Handler
typeRequest handler function executed when an HTTP route is matched.
type Handler<TParams extends RouteParams = RouteParams> = (ctx: Context<TParams>) => Response | Promise<Response>- ctx
- The typed request context containing `req`, `params`, `query()`, `json()`, etc.
Returns A web-standard `Response` or a promise resolving to a `Response`.
const handler: Handler<{ id: string }> = async (ctx) => { return API.json({ userId: ctx.params.id });};Method
typeSupported HTTP method strings.
type Method = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS"Middleware
typeOnion-style middleware function executed in the request pipeline.
type Middleware<TParams extends RouteParams = RouteParams> = (ctx: Context<TParams>, next: () => Response | Promise<Response>) => Response | Promise<Response>- ctx
- The typed request context.
- next
- Function to invoke the next middleware or final route handler in the chain.
Returns A web-standard `Response` or a promise resolving to a `Response`.
api.use(async (ctx, next) => { const start = performance.now(); const response = await next(); const duration = performance.now() - start; response.headers.set("X-Response-Time", `${duration.toFixed(2)}ms`); return response;});RouteParams
type============================================================================
OVERVIEW: Provides lightweight, high-performance HTTP routing, onion middleware pipelines, type-safe route parameter extraction, schema validation (Zod, Valibot, ArkType), spec-compliant CORS preflight, cookie parsing & encoding, and streaming responses. KEY EXPORTS: - `createAPI(path?)`: Factory to instantiate an `API` router instance. - `API`: Class managing HTTP method handlers (`.get()`, `.post()`, `.put()`, `.patch()`, `.delete()`), middleware (`.use()`), error handling (`.onError()`), and CORS (`.cors()`). Supports static response helpers: `API.json()`, `API.text()`, `API.stream()`, `API.cookie()`. - `Context`: Rich request wrapper passed into handlers/middleware offering: - `ctx.req`: Native `Request` object. - `ctx.params`: Typed route parameters inferred from path strings (e.g. `[id]`). - `ctx.query()`: Parsed query string dictionary. - `ctx.json(schema?)`: Safe body parser with optional validator parsing. - `ctx.formData(schema?)`: Multipart/urlencoded parser. - `ctx.cookies()`: Request cookies decoded into key-value map. - `ctx.state`: Mutable context bag for middleware state sharing (e.g. auth user). - `HttpError` & `ValidationError`: Standard status-carrying error classes. - `routeRequest(req)`: FileSystemRouter dispatcher for Next.js-style file-based APIs. QUICKSTART / USAGE: ```ts // src/backend/user/index.ts import { API, createAPI } from "../../types/api"; import { z } from "zod"; const api = createAPI(); // Middleware api.use(async (ctx, next) => { ctx.state.startTime = Date.now(); return await next(); }); // GET /user api.get(async (ctx) => { return API.json({ user: "Alice", query: ctx.query() }); }); // POST /user api.post(async (ctx) => { const body = await ctx.json(z.object({ name: z.string() })); return API.json({ created: body.name }, { status: 201 }); }); export default api; ``` Route parameter map representing key-value pairs extracted from dynamic URL paths.
type RouteParams = Record<string, string>// For route "/users/[id]" visited at "/users/42"const params: RouteParams = { id: "42" };AuthConfig or JobPayload — declaring your schema once is enough for the rest to follow. See Typed keys.