Express
Use rest-rpc with Express
Install
pnpm add @rest-rpc/express
Usage
import { registerRoutes, router } from "@rest-rpc/express";
import express from "express";
import { api } from "./contract";
const app = express();
app.use(express.json());
const routes = router(api, {
todos: {
list() {
return listTodos();
},
get({ id, context }) {
const authorization = context.req.header("authorization");
return getTodo(id, { authorization });
},
create({ title }) {
return createTodo({ title });
},
},
});
registerRoutes(app, routes);
app.listen(3000);
Framework Context
type HttpRouteHandlerContext = {
req: Request;
signal: AbortSignal;
};
type WebSocketRouteHandlerContext = {
req: IncomingMessage;
};
Options
type RegisterRoutesOptions = {
errorHandlers?: ServerErrorHandlers<
| { kind: "http"; req: Request; signal: AbortSignal }
| { kind: "websocket"; req: IncomingMessage; signal: AbortSignal }
>;
webSocket?: ExpressWebSocketOptions;
};
Error Handlers
registerRoutes(app, routes, {
errorHandlers: {
onRequestValidationError: ({ issues }) => ({
status: 422,
body: { code: "VALIDATION_ERROR", issues },
}),
onUnhandledError: () => ({
status: 500,
body: { code: "INTERNAL_SERVER_ERROR" },
}),
},
});
WebSocket
import { createServer } from "node:http";
import { WebSocketServer } from "ws";
const server = createServer(app);
const webSocketServer = new WebSocketServer({ noServer: true });
registerRoutes(app, routes, {
webSocket: {
server,
webSocketServer,
beforeUpgrade: ({ context }) => {
const authorization = context.req.headers.authorization;
return authorization ? undefined : { status: 401 };
},
},
});
server.listen(3000);