tRPC: The API Chef's secret ingredient for a delicious and safe dish

Mark Ezema

Mark Ezema / January 19, 2023

4 min read

Table of Contents

  1. Why use tRPC?
  2. How is tRPC used?
  3. How to call tRPC externally?
  4. Conclusion

Why use tRPC?

Interfacing with APIs can sometimes feel like trying to solve a Rubik's cube blindfolded. You know what you want the end result to look like, but getting there can be a real headache. That's where tRPC comes in... With its built-in features and best practices, tRPC helps you avoid common mistakes and interact with APIs in a typesafe and efficient way. Think of it as your personal API Yoda, guiding you through the process and providing autocompletion to help you move fast without falling to the Dark Side.

But wait, if you're familiar with GraphQL codegen, you might be thinking, "How is tRPC different?" The key difference is that tRPC allows you to create end-to-end typesafe APIs without any code generation or runtime bloat. This results in a closer relationship between the frontend and backend, and a fantastic developer experience.

To understand tRPC better, let's use some analogies:

  • Building a house: tRPC is like a set of blueprints and tools that help builders construct a safe and efficient house (API) without making mistakes and ensuring that all the rooms (endpoints) are connected and work well together (closer relationship between frontend and backend).
  • Playing a game: tRPC is like a set of rules and guidelines that help players (developers) make the right moves and win the game (create a typesafe and efficient API) without cheating (without code generation or runtime bloat).
  • Cooking a dish: tRPC is like a recipe book and set of kitchen tools that help cooks (developers) prepare a delicious and safe dish (API) without making mistakes.

How is tRPC used?

On the backend, tRPC allows developers to create procedures, similar to rooms in a building, which can be accessed by different routes like a floor in a building. Each procedure has its own validation system Zod to make sure that only authorized input can access the procedure, similar to how a security guard checks IDs at the building's entrance. And it also has a resolver function that retrieves data from the database and returns it to the client-side.

A simple tRPC procedure could look like this:

const userRouter = createTRPCRouter({
  getById: publicProcedure.input(z.string()).query(({ ctx, input }) => {
    return ctx.prisma.user.findFirst({
      where: {
        id: input,
      },
    });
  }),
});

On the frontend, tRPC provides a wrapper for @tanstack/react-query which allows for easy access to the procedures using the api object, similar to how a tenant in a building uses the elevator to access their floor. The autocompletion and typesafety features of tRPC are like having a directory in the building lobby that lists all the available procedures and the input they require, so the tenants know which floor to go to and what to expect once they get there.

A procedure call from our frontend could look like this:

import { useRouter } from "next/router";
import { api } from "../../utils/api";

const UserPage = () => {
  const { query } = useRouter();
  const userQuery = api.users.getById.useQuery(query.id);

  return (
    <div>
      <h1>{userQuery.data?.name}</h1>
    </div>
  );
};

Want to call your procedures externally?

With regular APIs, you can call your endpoints using any HTTP client such as curl, Postman, fetch or straight from your browser. With tRPC, it’s a bit different.

If you want to call your procedures without the tRPC client, there are two recommended ways to do it:

  1. Expose a single procedure externally

  2. Exposing every procedure as a REST endpoint

You can think about the two ways as similar to how you can make a phone call to a specific extension or the main line. If you want to expose a single procedure externally, it's like calling a specific department and talking to that department's representative. On the other hand, exposing every procedure as a REST endpoint is like calling the main line and being transferred to the appropriate department.

Conclusion

In conclusion, tRPC provides developers with built-in features and best practices to help avoid common mistakes and interact with APIs in a typesafe and efficient way. With tRPC, you can create end-to-end typesafe APIs without any code generation or runtime bloat, resulting in a closer relationship between the frontend and backend, and an amazing developer experience.

Subscribe to the newsletter

Get emails from me about updates in the world of Artificial Intelligence, and Personal Development.

View all issues