Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

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:

  1. Install tRPC and required dependencies:
  2. npm install @trpc/server @trpc/client
  3. Create a tRPC router:
  4. 
    import { createRouter } from '@trpc/server';
    
    const appRouter = createRouter()
      .query('getUser', {
        input: z.string(),
        resolve({ input }) {
          return getUserById(input);
        },
      });
                
  5. Integrate the router with your server:
  6. 
    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.