Skip to content

REST Handler

createRestHandler(router) returns an HTTP handler. It matches a request to a route, runs its auth middleware, and returns the route’s QueryPlan plus parsed params — or a RestResponse (e.g. 403) if auth fails.

import { createRouter, createRestHandler, crudRoutes } from "@mountsqli/api";
import { users } from "./tables";
const router = createRouter();
router.use(crudRoutes(users.def));
const handle = createRestHandler(router);
// inside your server:
const out = await handle(restReq); // MUST be awaited
if ("status" in out) {
return res.status(out.status).json(out.body); // e.g. 403
}
// out.route / out.plan / out.params

crudRoutes(tableDef) wires the standard endpoints:

Method Path Action
GET /<table> list (with filter + pagination)
POST /<table> create
GET /<table>/:id one
PUT /<table>/:id update
DELETE /<table>/:id delete

parseFilterQuery and paginationMeta turn query strings into plan filters:

const filter = parseFilterQuery(req.query, ["age", "email"]);
const meta = paginationMeta(req.query, total);

A route’s auth middleware is awaited. On rejection, the handler returns { status: 403, body: { error: "Forbidden" } }. Do not fire-and-forget it.

External errors become ProblemDetail via mountErrorToProblem. Raw detail stays out of the user-facing message.

  • Use crudRoutes for standard tables; add custom routes for business logic.
  • Always await handle(...).
  • Return out.body with out.status for non-query results.
  • Forgetting await — auth bypass.
  • Putting raw SQL in handlers instead of a QueryPlan.