Lesson Description

The "What is tRPC?" Lesson is part of the full, Fullstack TypeScript, v2 (feat. Zod) course featured in this preview video. Here's what you'd learn in this lesson:

Steve introduces tRPC, which allows developers to easily build & consume fully typesafe APIs without schemas or code generation. Full-stack projects using TypeScript can share types directly between client and server applications. Developers enjoy the ergonomics because the API endpoints resemble function calls.

Preview
Close

Transcript from the "What is tRPC?" Lesson

[00:00:00]
>> Steve Kinney: All right, so let's talk about another approach called tRPC. You might have also heard of things like gRPC. The idea is the same, it's just the first letter that is different, right? tRPC, the T stands for TypeScript. gRPC, the G stands for Google, who also own the language Go, which is the first two letters of Google.

[00:00:26]
But the RPC part is the part that's the same, which is this idea of a remote procedure call. The caveat obviously, if we have not figured that out already, is that this one does. It theoretically implies that your API is in TypeScript. Now, a pattern that exists for lots of reasons, most of which should be somewhat obvious is, there is a pattern sometimes called back end for front end, which is.

[00:00:56]
And there are lots of reasons why you might do this pattern, Walmart did it famously for a while, which is, you put, if you don't like the API contract in your back end. And we're not just talking about, you don't like it because it's gross. You don't like it because it's in Fortran, right?

[00:01:15]
I think Walmart had to do this where you kind of paper over your older legacy APIs that are like SOAP or XML or whatever, in, you paper over it once, so that everyone in the company doesn't ever have to deal with it again, right? And so even if the backend team is maybe in a different language and you can't make use of this, you can still put a layer over where you can then ultimately use this one.

[00:01:41]
So just because your backend is not in TypeScript does not mean that this approach is off the table. But like, super useful if you need a very, very flexible API, you still might want to consider like, something like this if for instance, you do have, very heavy API responses from a legacy API.

[00:01:58]
There are parts to this where even if the furthest backend backend is not in TypeScript, you might choose to do this. Because sometimes doing this stuff server side, close to the data is easier than sending everything over the wire to deal with it. Particularly if you're working with mobile or like low bandwidth, stuff like that.

[00:02:15]
And the nice part is, again, once you define the kind of contract, you can begin to generate all of the rest and keep those contracts in place versus having to implement it all by hand. So like I said, especially too, it's like, hey, we're still figuring out what this experience is and we don't necessarily even know what the API contract ought to have been, right?

[00:02:44]
It becomes incredibly useful. And sometimes you end up in legacy situations, right? A company that I worked at that sends emails for a living, to actually construct the current user was like six API calls, right, and then you could wire that all together. Now, you can do that client-side, right, or you can choose to put layers that abstract that, so on and so forth.

[00:03:10]
And sometimes you didn't need all that data. Lots of reasons why you might take this approach. But effectively, it sits, the services could be, microservice is my backend written in other languages. It could even be ones in Node, your databases, so on and so forth. But again, you are just trying to put an abstraction over that, that that will then let you build on top of it and resolve it as we go along.

[00:03:32]
So there is a little bit of kinda pieces in here. This is the client side where you just grab the type of the route. It's not dissimilar from what we just saw with the OpenAPI schemas, where we could generate an entire client just based on the types. You can do very something very similar here as well.

[00:03:53]
And what's kind of cool about it is it will send stuff, you can even do, like updates over WebSockets. It's all kind of built in. And you begin to just say what you want to grab. And we'll see it in practice. It'll be a little better. This is the fits on a slide version.

[00:04:07]
So this is the server side implementation, where you would grab the @trpc/server, you kind of just go ahead and create a server. And then you have a router, right? And so for instance, this router will support, again, hello, which will send back this string. And, like, we just export the type.

[00:04:24]
So we just effectively are coming up with a contract. This contract is interesting because it also gets to be the implementation, right? So now, if somebody wants to call the Hello procedure, right? Basically, it's almost like, instead of calling APIs and getting responses back, think of it like you can remotely call functions on the server and get the stuff back.

[00:04:42]
So this procedure is really, you can basically call hello and you're going to get back this string. You're not necessarily worried about what's the path for that and what are, all those things. It's basically a contract that is exposed to you that then all the transport will be handled for you.

[00:05:00]
On the client, again, you can see that we do create the proxy client, but then we can just call trpc.hello, and query it, versus mutate it, so on and so forth. Some of these terms might sound like GraphQL, and if you've never used GraphQL, you don't need to know anything about GraphQL.

[00:05:16]
So it's fine. And then call it, and so we can call different things with different parameters, only get back part of the data that we want and send less over the wire. With a regular old HTTP request, obviously, if you hit that endpoint, you could get fancy with the query params and what you do and don't want to see, but you're doing a lot of that by hand.

[00:05:35]
This kind of gives you the ability to call things as you need it and pass in options. And when we see it in practice, it's pretty, pretty nice. So it does, again, it is in TypeScript. So for a lot of smaller things, definitely like useful. It is not a totally separate kind of server, where you're installing Apollo or whatever to get GraphQL support.

[00:06:01]
It is just effectively TypeScript at the end of the day. But it allows you to be very custom. It does have some caveats, which, again, only for TypeScript. Like you probably, either you own the backend for the frontend, or you own the backend, right? But generally speaking, you probably want to own at least some server side component as well.

[00:06:21]
Obviously, it's tricky. We did it to great success at Twilio, but also, you know what everything supports? Regular old HTTP and REST clients. There's always going to be better tooling for that stuff despite all of the things I just told you about why this is great. But again, in the ways of solving this problem that we've been tackling from multiple different angles, it's a particularly interesting.

[00:06:48]
At the very least, knowing that it exists in case you need it is probably also worth your time, even if you don't have an immediate use, cuz it solved a very, very large problem for us. So, where does it fit? All-in on TypeScript? Definitely, we used it for a large project because we were young and stupid, but it worked out, so who cares?

[00:07:10]
But we also were trying to create one abstraction because every team was putting their own abstraction over the Java backends and whatever. We were trying to solve a different problem with it. But mostly that third bullet point of many, many different teams needing to do slightly different things as we go along.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now