Skip to content

defineHandler

The defineHandler function is the core building block for creating API endpoints in TApi. It ensures end-to-end type safety by connecting your request schema validation with your implementation logic.

import { defineHandler, TResponse } from "@farbenmeer/tapi/server";
import { z } from "zod";
export const GET = defineHandler({
authorize: () => true,
query: {
limit: z.coerce.number().min(1).default(10)
}
}, async (req) => {
const { limit } = req.query();
return TResponse.json({ limit });
});
function defineHandler<Response, AuthData, Params, Query, Body>(
schema: Schema<Response, AuthData, Params, Query, Body>,
handler: (req: TRequest<AuthData, Params, Query, Body>) => Promise<TResponse<Response>>
): Handler

An object defining the input validation, authorization logic, and response structure.

PropertyTypeDescription
authorize(req: TRequest) => AuthDataRequired. A function that determines if the request is allowed. Throw an error to deny access. The return value is accessible via req.auth().
paramsZodSchema (object)Optional. Zod schema for validating path parameters (e.g., /users/:id).
queryZodSchema (object)Optional. Zod schema for validating query string parameters.
bodyZodSchemaOptional. Zod schema for validating the JSON request body.
responseZodSchemaOptional. Zod schema to define the expected response shape. Currently used for OpenAPI generation.

The implementation function that receives the validated request and returns a response.

  • Arguments: req - A TRequest object containing validated data.
  • Returns: A promise resolving to a TResponse.
export const GET = defineHandler({
authorize: () => true
}, async () => {
return TResponse.json({ message: "Hello World" });
});

For a route defined as /users/:id:

export const GET = defineHandler({
authorize: () => true,
params: {
id: z.string().uuid()
}
}, async (req) => {
const { id } = req.params();
return TResponse.json({ userId: id });
});
export const POST = defineHandler({
authorize: (req) => {
if (!req.headers.get("Authorization")) throw new Error("Unauthorized");
return { userId: "current-user" };
},
body: z.object({
title: z.string().min(3),
content: z.string()
})
}, async (req) => {
const user = req.auth();
const { title, content } = await req.data();
// Perform database operation...
return TResponse.json({ success: true, author: user.userId });
});