API Reference
Every reusable framework capability is exposed through one import — the facade at @/framework/facade.js. You never reach into framework internals; if it is not on this page, it is not part of the public API.
ts
import {
createRouter, // router builder
createRoute, // OpenAPI route declaration
group, // middleware grouping shorthand
z, // Zod + .openapi() schemas
jsonContent, // JSON media-type wrapper
HttpStatusCodes,// status constants
validate, // schema validation outside routes
database, // init/access the Drizzle instance
db, // global query proxy
paginate, // request-driven pagination
paginateModel, // eager-loading pagination
paginateQuery, // custom count/data pagination
paginateTable, // single-table pagination
cache, // Redis key-value cache
command, // register in-process handler
dispatchCommand,// run an in-process handler
dispatchEvent, // broadcast and/or enqueue an event
queue, // access a BullMQ queue
queueJob, // enqueue a background job
shouldQueue, // register a job handler
broadcast, // Socket.IO broadcast
defineSchedule, // named cron schedules
session, // server-side sessions
storage, // file storage
notify, // persisted + realtime notifications
password, // bcrypt hashing
jwt, // token generation/verification
cookie, // auth cookie helpers
mail, // SMTP transport
logger, // structured logging
urls, // absolute URL building
lodash, // full Lodash library
} from "@/framework/facade.js";Function reference
Each facade function has its own page. Every export below is a documented part of the public API.
| Function | Purpose | Guide |
|---|---|---|
createRouter | Hono router with group/route/api helpers | Routing · OpenAPI |
createRoute | Declare a documented OpenAPI route | Routing · OpenAPI |
group | createRouter().group() shorthand + role middleware | Routing |
z | Extended Zod with .openapi() | OpenAPI |
jsonContent | Wrap a schema as application/json | OpenAPI |
HttpStatusCodes | Numeric HTTP status constants | OpenAPI |
validate | Run a Zod schema → throws 422 on mismatch | OpenAPI |
database | Returns the initialized Drizzle instance | Database |
db | Global Drizzle query proxy | Database |
paginate | Request-driven pagination (joins, aggregates) | Database |
paginateModel | Eager-loading pagination (db.query…findMany with) | Database |
paginateQuery | Manual total()/data() pagination | Database |
paginateTable | Single-table pagination, no request object | Database |
cache | Redis key-value cache (graceful fallback) | Cache |
command | Register an in-process synchronous handler | Events & Queue |
dispatchCommand | Run a registered command (async: enqueue) | Events & Queue |
dispatchEvent | Broadcast + enqueue a domain event | Events & Queue |
queue | Access a BullMQ queue instance | Events & Queue |
queueJob | Enqueue a background job | Events & Queue |
shouldQueue | Register a job handler (optionally durable) | Events & Queue |
broadcast | Socket.IO emit to targeted audiences | Realtime |
defineSchedule | Named cron tasks with distributed locking | Scheduler |
session | Redis-backed server-side sessions | Session |
storage | Local + S3-compatible file storage | Storage |
notify | Persist + broadcast + email notifications | Notifications |
password | bcrypt hash / verify | Password |
jwt | HS256 token generation / verification | JWT |
cookie | {name}_access / {name}_refresh cookie helpers | Cookie |
mail | SMTP sendMail transport | |
logger | Leveled structured logging + rotating files | Logger |
urls | Absolute URL building from APP_URL | URL |
lodash | Full Lodash re-export | libraries |
When do I use which?
- HTTP & OpenAPI —
createRouter/groupbuild the router;createRoutedocuments a route;zwrites the schemas;jsonContent+HttpStatusCodesdescribe responses. - Input safety —
validateruns a schema anywhere (outside routes) and throws a structured422on failure. - Data —
dbis the Drizzle client;paginate/paginateModel/paginateQuery/paginateTablewrap queries in a Laravel-style page (see the Which one? table). - Caching —
cachestores JSON with TTL and degrades to a no-op when Redis is off. - Background work —
command/dispatchCommandrun in-process handlers;dispatchEventfans out to sockets and/or queues;queueJob/shouldQueueare the raw BullMQ surface. - Realtime —
broadcastemits a Socket.IO event to targeted audiences. - Automation —
defineScheduleruns cron tasks with distributed locking. - State & files —
sessionkeeps server-side state;storagereads/writes files on local disk or S3. - User-visible events —
notifypersists a notification row and optionally broadcasts + emails it. - Support —
password,jwt,cookie,mailpower auth flows;loggeris the structured logger;urlsbuilds absolute links;lodashre-exports the full library.
Common recipes
Sign up a user with hashed password + realtime + email
The auth flow composes hashing, persistence, and dispatch:
ts
import { db, password, dispatchEvent, notify } from "@/framework/facade.js";
import * as schema from "@/database/schema.js";
export const register = async (input: { name: string; email: string; password: string }) => {
const user = await db.insert(schema.users).values({
name: input.name,
email: input.email,
password: await password.hashPassword(input.password),
});
await notify(user.id, {
type: "success",
title: "Welcome",
body: "Your account is ready.",
broadcast: true,
mail: { subject: "Welcome to nexgen" },
});
await dispatchEvent("user.registered", { userId: user.id }, { broadcast: { roles: ["admin"] } });
return user;
};List a paginated resource
Route + controller compose routing, querying, and pagination:
ts
import { createRoute, createRouter, group, HttpStatusCodes, jsonContent, db, paginate, z } from "@/framework/facade.js";
import { desc } from "drizzle-orm";
import { posts } from "@/modules/blog/database/models/post.js";
const listRoute = createRoute({
path: "/",
method: "get",
tags: ["Posts"],
responses: {
[HttpStatusCodes.OK]: jsonContent(z.array(PostSchema), "list of posts"),
},
});
export default createRouter().group().api(listRoute, async (c) => {
const query = db.select().from(posts).orderBy(desc(posts.id));
return c.json(await paginate(c, query, 15));
});Throttle background work and broadcast the result
queueJob + shouldQueue handle heavy work; broadcast surfaces the outcome:
ts
import { queueJob, shouldQueue, broadcast } from "@/framework/facade.js";
// Controller: queue it, respond fast
await queueJob("process-image", { path }, { queue: "images", delay: 5 });
// Worker: register handler, then notify the author
shouldQueue("process-image", "images", async (job) => {
const url = await processImage(job.data.path);
broadcast("image.processed", { url }, { users: [job.data.userId] });
});Rules of the facade
- One import — everything importable lives on
@/framework/facade.js; the facade only re-exports what is implemented. If a function is missing here, it does not exist yet. - Graceful degradation — Redis-backed features (
cache,session,queue,broadcastvia adapter) returnnull/false/fallbackwhen Redis is unavailable instead of throwing. - Namespaces over bare functions — grouped utilities (
cache,session,storage,jwt,cookie,password,mail,urls,lodash) keep call sites searchable and collide-proof. - Compose, don't re-implement — features are built by combining the exports above (see the pagination helpers, which all share one
PaginatedResultshape).
