Express
Express Extension
Section titled “Express Extension”A thin, optional adapter over the HTTP transport core, which owns the route table, envelopes and hooks. This page covers only what is Express-specific.
Requires Express 5, whose route syntax the middleware is written against. NestJS has been on Express 5 since v11, so a current Nest app already qualifies.
Quick start
Section titled “Quick start”import express from 'express';import { querierMiddleware } from 'uql-orm/express';import './uql.config.js'; // setQuerierPool + entity importsimport { Post, User } from './shared/models/index.js';
const app = express();app.use(express.json()); // required by the write routes and the QUERY transport
app.use('/api', querierMiddleware({ include: [User, Post] }));
app.listen(3000);That mounts the full wire protocol per entity, including the QUERY transport. Unknown entities and routes fall through via next(), so your own routes (webhooks, payments, SSE) share the prefix.
:id is not hardcoded: the route parameter maps to whatever property carries @Id(), so uuid or itemNo work unchanged.
The core’s hooks apply, with ctx.context bound to the express.Request:
app.use('/api', querierMiddleware({ include: [User, Post], async pre({ context }) { if (!context.user) { throw Object.assign(new Error('unauthorized'), { status: 401 }); // numeric status becomes the HTTP status } }, preSave(ctx) { ctx.body = { ...(ctx.body as object), creatorId: ctx.context.user.id }; },}));For tenant isolation pass getContext plus a security filter rather than folding $where in preFilter: it scopes every query in the request, cannot be bypassed from the wire, and fails closed. See Multi-tenancy.
Error handling
Section titled “Error handling”Errors go to next(err), so your own error middleware keeps working. The exported errorHandler renders the canonical envelope and honors a numeric status thrown by a hook:
import { errorHandler } from 'uql-orm/express';
app.use('/api', querierMiddleware({ include: [User] }));app.use(errorHandler);