API routes and middleware
Answer HTTP requests with files in api/, and run code on each request with files in middleware/.
Last page, a page loaded its data from a server. That server can be your own app.
Pages return HTML. For JSON, webhooks, or health checks, you want a plain function. It takes a request and returns a response.
Think of api/ as a second street map next to pages/. It uses the same address rules. The file name can also say which HTTP method it answers.
Pick a method and an address. Then press Send.
Which file answers this request?
Pick GET or POST and an address. Then press Send.
GET /api/users/42
Nothing sent yet. Press Send.
- middleware/request.tsruns for each page and endpoint
- pages/about.tsrx/about
- pages/404.tsrxpages with no match
- api/health.ts/api/health, every method
- api/users/[id].get.ts/api/users/ and an id, GET only
- Nothing yet. Press Send.
Simplified. We sent each of these requests to an app made from the full-stack starter, with these files added. The list leaves out pages/index.tsrx. A 404 response did not carry the middleware header in our runs, so the figure does not mark the middleware for it.
Notice that POST /api/users/42 gets a 404. The file name says get.
One file, one endpoint
import type { EndpointHttpContext } from '@markless/router';
export const cache = { maxAge: 60 };
export default function user({ params }: EndpointHttpContext<{ id: string }>) {
return Response.json({ id: params.id });
}
GET /api/users/42 returns {"id":"42"} with cache-control: public, max-age=60, s-maxage=60.
File in api/ |
Answers |
|---|---|
health.ts |
every method on /api/health |
index.ts |
/api |
users/[id].get.ts |
only GET on /api/users/:id |
files/[...path].ts |
/api/files/ plus one segment or more |
Method names for the file: get, post, put, patch, delete, head, options, connect, trace.
The function gets one object with request, url, params, locals, and response. Set headers on response.headers, or return your own Response.
The only cache form is export const cache = { maxAge: <seconds> }.
Middleware
A file in middleware/ runs for each request to your pages and endpoints. The full-stack starter ships this one:
export default function request(http: import('@markless/router').MiddlewareHttpContext) {
http.response.headers.set('x-markless-router', '1');
}
That header shows on pages and on /api/ responses. It does not show on the 404 page.
Next: How do these files become a server you can run? Building and deploying →
