Docs
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.

src/routes/products/route.js
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: true mounts the route under an /api prefix, so path: "/products" is served at /api/products. Leave it off (or false) to mount at the bare path.
  • authentication: { api_key: true } requires a valid KORA.API_KEY bearer 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.