Skip to content

How to Add a New Route

This guide documents the complete workflow for adding a new HTTP endpoint to the Workers backend, ensuring the OpenAPI spec is generated automatically and the route is validated.

Flow (4 steps)

text
┌──────────┐   ┌──────────┐   ┌──────────────┐   ┌──────────┐
│ 1. Handler │ → │ 2. Router │ → │ 3. Registry  │ → │ 4. Build │
└──────────┘   └──────────┘   └──────────────┘   └──────────┘

Step 1 — Create the handler

In workers/src/routes/, create or edit the file for your entity.

Rules:

  • Use createHandler(fn) from middleware/handler.ts
  • Receive the body via parseBody(request, schema) with Zod schema
  • Respond with json({...})
  • Use requireAuth and requireRole for access control
  • Use idempotentMutation for mutating endpoints
typescript
// workers/src/routes/customers.ts
import { createHandler, parseBody, json } from "../middleware/handler";
import { requireAuth, requireRole } from "../middleware/auth";
import { z } from "zod";

export const customerSchema = z.object({
  name: z.string().min(1).max(100),
  email: z.string().email(),
});

export const handleCreateCustomer = createHandler(async (request, env, _ctx, corrId) => {
  const principal = await requireAuth(request, env);
  requireRole(["ADMIN"])(principal);
  const payload = await parseBody(request, customerSchema);

  // ... business logic ...

  return json({ id: "uuid", serverTime: new Date().toISOString() }, 201);
});

Step 2 — Register in the router

In workers/src/router.ts, import the handler and add the route:

typescript
// 1. Import (at the top)
import { handleCreateCustomer } from "./routes/customers";

// 2. Register (in the createRouter function)
routes["POST /api/v1/customers"] = { handler: handleCreateCustomer };

Step 3 — Register in the OpenAPI registry

In scripts/openapi-registry.ts, add an entry in the routeRegistry array (routes are declared with route() helper and declarative middlewares in router.ts):

typescript
{
  method: "POST",
  path: "/api/v1/customers",
  summary: "Create customer",
  description: "Creates a new customer record.",
  tags: ["Customers"],
  auth: "admin",
  requestSchema: customerSchema,             // ← from your schemas file
  requestExample: {
    name: "João Exemplo",
    email: "joao@exemplo.com",
  },
  responseSchema: createResponseSchema,      // ← reuse or create a new one
  responseDescription: "Customer created",
  statusCodes: [201, 400, 401, 403],
},

Required fields: method, path, summary, tags, auth, statusCodes.

Optional fields: description, requestSchema, requestExample, responseSchema, responseDescription.

Step 4 — Validate and generate

bash
pnpm docs:openapi     # Validates coverage + generates openapi.json
pnpm docs:build       # Runs everything above + builds the portal

If step 2 or 3 is missing, the build fails with a clear error.

auth Values

ValueMeaning
"none"Public endpoint (health, login)
"bearer"Any authenticated user
"admin"Requires ADMIN role
"cadastro"Requires ADMIN or CADASTRO
"chamador"Requires ADMIN or CHAMADOR
"relatorios"Requires ADMIN or RELATORIOS

Automatic Validation

The scripts/generate-openapi.ts script performs two checks:

  1. Every route in router.ts has a registry entry — if missing, error and build breaks
  2. No orphan registry entries — warning if there's an entry without a matching route

⚠️ If you add a new route and forget to register it in OpenAPI, pnpm docs:build fails with Route GET /api/v1/customers is NOT documented.

Distribuído sob licença MIT.