Usage with Fastify
Example app
The best way to start with the Fastify adapter is to take a look at the example application.
Description | Links |
---|---|
|
How to use tRPC with Fastify
Install dependencies
yarn add @trpc/server fastify fastify-plugin zod
Zod isn't a required dependency, but it's used in the sample router below.
Create the router
First of all you need a router to handle your queries, mutations and subscriptions.
A sample router is given below, save it in a file named router.ts
.
router.ts
import * as trpc from '@trpc/server';
import { z } from 'zod';
type User = {
id: string;
name: string;
bio?: string;
};
const users: Record<string, User> = {};
export const appRouter = trpc
.router()
.query('getUserById', {
input: z.string(),
async resolve({ input }) {
return users[input]; // input type is string
},
})
.mutation('createUser', {
// validate input with Zod
input: z.object({
name: z.string().min(3),
bio: z.string().max(142).optional(),
}),
async resolve({ input }) {
const id = Date.now().toString();
const user: User = { id, ...input };
users[user.id] = user;
return user;
},
});
// export type definition of API
export type AppRouter = typeof appRouter;
If your router file starts getting too big, split your router into several subrouters each implemented in its own file. Then merge them into a single root appRouter
.
Create the context
Then you need a context that will be created for each request.
A sample context is given below, save it in a file named context.ts
:
context.ts
import { inferAsyncReturnType } from '@trpc/server';
import { CreateFastifyContextOptions } from '@trpc/server/adapters/fastify';
export function createContext({ req, res }: CreateFastifyContextOptions) {
const user = { name: req.headers.username ?? 'anonymous' };
return { req, res, user };
}
export type Context = inferAsyncReturnType<typeof createContext>;
Create Fastify server
tRPC includes an adapter for Fastify out of the box. This adapter lets you convert your tRPC router into an Fastify plugin.
import fastify from 'fastify';
import fp from 'fastify-plugin';
import { fastifyTRPCPlugin } from '@trpc/server/adapters/fastify';
import { createContext } from './context';
import { appRouter } from './router';
const server = fastify();
server.register(fp(fastifyTRPCPlugin), {
prefix: '/trpc',
trpcOptions: { router: appRouter, createContext },
});
(async () => {
try {
await server.listen(3000);
} catch (err) {
server.log.error(err);
process.exit(1);
}
})();
Your endpoints are now available via HTTP!
Endpoint | HTTP URI |
---|---|
getUser | GET http://localhost:4000/trpc/getUserById?input=INPUT where INPUT is a URI-encoded JSON string. |
createUser | POST http://localhost:4000/trpc/createUser with req.body of type User |
How to enable subscriptions (WebSocket)
The Fastify adapter supports subscriptions via the fastify-websocket plugin. All you have to do in addition to the above steps is install the dependency, add some subscriptions to your router and activate the useWSS
option in the plugin.
Install dependencies
yarn add fastify-websocket
Import and register fastify-websocket
import ws from 'fastify-websocket';
server.register(ws);
Add some subscriptions
Edit the router.ts
file created in the previous steps and add the following code:
export const appRouter = trpc
.router()
// .query(...)
// .mutation(...)
.subscription('randomNumber', {
resolve() {
return new Subscription<{ randomNumber: number }>((emit) => {
const timer = setInterval(() => {
emit.data({ randomNumber: Math.random() });
}, 1000);
return () => {
clearInterval(timer);
};
});
},
});
Activate the useWSS
option
server.register(fp(fastifyTRPCPlugin), {
useWSS: true,
// ...
});
It's alright, you can subscribe to the topic randomNumber
and you should receive a random number every second ๐.
Fastify plugin options
name | type | optional | default | description |
---|---|---|---|---|
prefix | string | true | "/trpc" | |
useWSS | boolean | true | false | |
trpcOptions | NodeHTTPHandlerOptions | false | n/a |