API routes
Drop a file in src/api/ and export HTTP-method handlers — they are served under
/api/*.
// src/api/hello.ts → /api/hello
export function GET() {
return Response.json({ message: 'hello' });
}
export function POST(request: Request) {
return Response.json({ method: 'POST' });
}
Export one function per method you support: GET, POST, PUT, PATCH, DELETE,
HEAD, OPTIONS. The directory is configurable through apiDir in fluixi.config;
src/api is the default.
Return values
A handler returns a Web Response, or any value — which is sent as JSON:
export function GET() {
return { ok: true }; // → application/json
}
export function GET() {
return Response.json({ ok: true }, { status: 201 }); // full control
}
export function GET() {
return new Response('plain', { headers: { 'content-type': 'text/plain' } });
}
Return a Response yourself when you need a status other than 200, custom headers, a
redirect, or a non-JSON body. The plain-value form exists so the common case stays short.
Params and catch-all
The file path is the route, with the same conventions as pages:
// src/api/users/[id].ts → /api/users/:id
export function GET(_req: Request, { params }: { params: { id: string } }) {
return Response.json({ id: params.id });
}
// src/api/files/[...path].ts → catch-all, /api/files/**
Params arrive as plain strings on the second argument, not as accessors — an API handler runs once per request, so there is nothing reactive about it.
Everything else about the request comes from the standard Request: the query string via
new URL(request.url).searchParams, the body via await request.json() or
await request.formData(), and headers via request.headers.
Status codes you get for free
A request to a path that exists but with a method you did not export returns 405, with
an Allow header listing the methods that file does export; an unknown /api/* path
returns 404. You do not need to write either.
API route or server function?
Both run only on the server, so the choice is about who calls them:
- A server function is for your own client code. It is typed end to end, and the call looks like a function call rather than a fetch.
- An API route is for callers you do not control — a webhook, a mobile app, a CLI, anything that needs a stable URL, a specific status code, or a non-JSON body.
If you are reaching for fetch('/api/…') inside your own app, a
server function is usually the shorter path.
Next: Middleware.