Skip to content
rest-rpc
Esc
navigateopen⌘Jpreview
On this page

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);

Was this page helpful?