Skip to content
NewComposite primary keys5 min read

Elysia

Elysia is fetch-native, so it mounts the HTTP transport core directly: .mount() strips the prefix before the handler sees the request. Nothing to install beyond uql-orm.

import { cors } from '@elysiajs/cors';
import { Elysia } from 'elysia';
import { createFetchHandler } from 'uql-orm/http';
import { pool } from './uql.config.js';
import { Post, User } from './shared/models/index.js';
const handler = createFetchHandler({ pool, include: [User, Post] });
new Elysia()
.use(cors())
.get('/health', () => 'ok')
.post('/checkout', ({ body }) => runCheckout(body)) // custom business logic
.mount('/api', handler) // entity CRUD under /api
.listen(3000); // Bun; on Node, `new Elysia({ adapter: node() })` from @elysiajs/node

That serves the full wire protocol per entity, QUERY included, since .mount() routes every method and forwards the body unparsed. It claims only the /api prefix, so your own routes, plugins and lifecycle hooks sit beside the generated CRUD; keep them for read-modify-write logic, multi-entity transactions, aggregations, uploads and streaming. Unknown routes under the prefix 404 from the handler rather than falling through.

The mount is optional. pool is a plain ORM, so any route can query it:

new Elysia().get('/posts', () =>
pool.findMany(Post, { $where: { published: true }, $limit: 20 }),
);

Work spanning several statements goes in pool.transaction, which hands you the querier to run all of them on.

Nothing here is Elysia-specific, so the core documents it once: getContext takes the web Request and scopes every query in it through a security filter, and the hooks shape a response, stamp a field or reject a payload. A hook that throws with a numeric status becomes that HTTP status.

.mount() is opaque to Elysia’s type system, so Eden Treaty sees nothing under /api: the typed client for it is UQL’s browser client, which sends the same query you write on the server. Eden keeps covering your hand-written routes. For per-procedure contracts, see tRPC and oRPC.