Developer Documentation
Routes
Expose an extension over HTTP with authenticated, JSON API endpoints.
Routes expose your extension over HTTP. Extend Routes, set a path, and add a method named after the
HTTP verb you want to answer (GET, POST, PUT, DELETE, PATCH). Routes load from every
route.js file at any depth under src/routes/, so the folder structure is up to you.
import { Routes } from "#kora/extensions";
export class Products extends Routes {
constructor(kora) {
super(kora, {
name: "Products",
path: "/products",
api: true,
authentication: { api_key: true }
});
}
GET() {
return this.kora.extensions.handlers.get(this.extension, "Products").listAll();
}
POST(request) {
const { name, ...options } = request.body;
return this.kora.extensions.handlers.get(this.extension, "Products").create(name, options);
}
}api: truemounts the route under an/apiprefix, sopath: "/products"is served at/api/products. Leave it off (orfalse) to mount at the bare path.authentication: { api_key: true }requires a validKORA.API_KEYbearer token and applies rate limiting. Public endpoints (like license validation) leave it off.- Whatever a method returns is sent as JSON. Return a value and Kora serialises it. If you need full
control, use the Express
response(the second argument) and write to it yourself; Kora then stays out of the way. - Errors thrown from a handler (including
fail()) become the matching status and{ error }body.
The request body is always parsed and defaulted to an empty object, so request.body is safe to
destructure even on requests without one.
Every request to a route emits an api.request event
once the response is sent, so you can log, audit, or track usage without touching each handler.

