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 }[]