Advanced tRPC Techniques
1. Introduction
tRPC (TypeScript Remote Procedure Call) provides a framework for building APIs with full type safety. This lesson covers advanced techniques for leveraging tRPC to build robust and efficient back-end applications.
2. Key Concepts
- Type Safety: Ensures that your API and client are in sync with types.
- Procedure: A function that can be called remotely.
- Router: A collection of procedures grouped under a single namespace.
- Middleware: Functions that can execute code before or after a procedure is called.
3. Setting Up tRPC
To set up tRPC in your project, follow these steps:
- Install tRPC and required dependencies:
- Create a tRPC router:
- Integrate the router with your server:
npm install @trpc/server @trpc/client
import { createRouter } from '@trpc/server';
const appRouter = createRouter()
.query('getUser', {
input: z.string(),
resolve({ input }) {
return getUserById(input);
},
});
import { inferAsyncReturnType, initTRPC } from '@trpc/server';
import express from 'express';
const createContext = ({ req, res }) => ({});
const t = initTRPC.context(createContext).create();
const app = express();
app.use('/trpc', t.createExpressMiddleware({ router: appRouter }));
4. Middleware in tRPC
Middleware can be used to execute logic before or after your procedures. Here’s how to implement a middleware:
const loggingMiddleware = t.middleware(async ({ ctx, next }) => {
console.log('Request received');
const result = await next();
console.log('Response sent');
return result;
});
const protectedProcedure = t.procedure.use(loggingMiddleware);
5. Error Handling
Effective error handling is crucial for API development. tRPC allows you to define custom error handling logic:
const appRouter = createRouter()
.query('getUser', {
input: z.string(),
resolve({ input }) {
const user = getUserById(input);
if (!user) {
throw new TRPCError({
code: 'NOT_FOUND',
message: `User with id ${input} not found`,
});
}
return user;
},
});
6. Testing tRPC Procedures
Testing is essential for ensuring your procedures work as expected. Use a testing framework like Jest:
import { createRouter } from '@trpc/server';
const appRouter = createRouter().query('getUser', {
resolve({ input }) {
return getUserById(input);
},
});
// Test case
test('getUser returns user data', async () => {
const user = await appRouter.getUser.query('123');
expect(user).toEqual({ id: '123', name: 'John Doe' });
});
7. Best Practices
Follow these best practices to ensure your tRPC API is effective:
- Use TypeScript for type safety and better developer experience.
- Implement middleware for common logic such as logging and authentication.
- Handle errors gracefully and provide meaningful feedback to clients.
- Write tests for your procedures to ensure reliability.
8. FAQ
What is tRPC?
tRPC is a TypeScript-first framework for building type-safe APIs.
How do I handle errors in tRPC?
You can throw a TRPCError with a specific code and message to handle errors gracefully.
Can I use middleware in tRPC?
Yes, middleware can be used to execute logic before or after a procedure is invoked.