ServerCRUD
API Reference
createCrudRoutes factory, generated endpoints, and typed RPC integration.
createCrudRoutes
Factory function in features/crud/crud.routes.ts that generates standard CRUD endpoints for any Prisma model.
Usage
import { createCrudRoutes } from "@/features/crud/crud.routes";
import { ContactFindManySchema, ContactCreateSchema } from "./schemas";
const contactRoutes = createCrudRoutes({
model: "contact",
schemas: {
findMany: ContactFindManySchema,
createOne: ContactCreateSchema,
findOne: ContactFindOneSchema,
updateOne: ContactUpdateSchema,
deleteOne: ContactDeleteSchema,
},
hooks: {
before: {
createOne: async (params) => {
// Transform params before creation
return params;
},
},
after: {
createOne: async (result) => {
// Side-effect after creation
},
},
},
});Generated Endpoints
Each call generates these POST endpoints:
| Endpoint | Operation |
|---|---|
/${model}/findOne | findOne |
/${model}/findMany | findMany |
/${model}/createOne | createOne |
/${model}/updateOne | updateOne |
/${model}/deleteOne | deleteOne |
/${model}/aggregate | aggregate |
/${model}/groupBy | groupBy |
Request Format
// POST /contact/createOne
const result = await client.contact.createOne.$post({
json: {
where: { id: "contact_123" }, // for update/delete
data: { name: "Alice" }, // for create/update
select: { id: true, name: true }, // field selection
}
});Response Format
{
data: { id: "contact_123", name: "Alice" },
meta: { requestId: "req_abc" }
}Typed RPC
The Hono RPC client automatically inherits types from Zod schemas:
// Frontend - fully typed
const contact = await client.contact.createOne.$post({
json: { data: { name: "Alice" } }
});
// TypeScript knows:
// contact: { id: string; name: string; ... }Internal Usage
For internal service-to-service calls, use the Effect-TS service directly:
import { CrudService } from "@/features/crud/services/crud.service";
import { PrismaTag } from "@/lib/tags";
const result = await Effect.runPromise(
CrudService.execute("contact", "createOne", params)
.pipe(Effect.provide(CrudServiceLive))
);