Skip to content

Server Best Practice

I recommend using superjson as the transformer. It is a superset of JSON that supports Dates, BigInts, and more. this is not required, but it is a good practice. using this transformer will make your life easier when working with dates, bigints, sets, maps, and other javascript/non-json types.

WARNING

Ensure that the client-side uses the same transformer.

Installation

sh
npm i @http-rpc/server superjson zod

Folder Structure

I suggest organizing your routes, endpoints, and router in separate files.

I create an rpc/ folder at the project's root and make these files:

  • rpc/route.ts
  • rpc/router.ts
  • rpc/routes/*.ts
ts
import { createRoute } from '@http-rpc/server';
import { FastifyContext } from '@http-rpc/server/adapters/fastify';

export const publicRoute = createRoute<FastifyContext>();
ts
import * as users from './routes/users/endpoints';
import * as orders from './routes/orders/endpoints';

export const router = {
	users,
	orders,
};
export type Router = typeof router;
ts
import { publicRoute } from '../../route';

export const findOne = publicRoute.get(async () => {
	return { name: 'John Doe' };
});
ts
export * as transactions from './transactions/endpoints';
ts
import { publicRoute } from '../../../route';

export const list = publicRoute.get(async () => {
	return [
		{ id: 1, amount: 100 },
		{ id: 2, amount: 200 },
	];
});

Here is an example of how the client will look like

ts
import { rpc } from '#rpc/client';

const user = await rpc.users.findOne.get();
//    ^? { name: string }

const transactions = await rpc.orders.transactions.list.get();
//    ^? { id: number, amount: number }[]

Released under the MIT License.