tRPC: Smart and Easy APIs

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
trpc it's a new way to define and implement node apis and if you've been looking to get into full stack this may be what you're looking for hi i'm jack harrington a principal full stack software engineer and on this video i'm going to break trpc down for you in three steps the first thing we're going to do is create a node express api server and put react on top of it we'll do that step by step and then we'll take a look at a next js application that has subscriptions and does chat and of course all of that is available to you for free on github and then i'll do some pros and cons at the end where we talk about how trpc stacks up against our existing api mechanisms it's fun stuff let's jump right into it okay i have an empty directory here called express react nvs code and i'm going to jump over to my gist this is listed in the description down below and i'll pull out this package.json this is basically a monorepo starter so i'm going to have two applications here the first is a node express api server and the second is our react app so those are going to need to actually connect and this is what's going to do that work for us it's a yarn workspace based package but it also works in things like npm pmpm or whatever so i'm going to go up here create a new file called package.json and just paste that on in there now the next thing i'm going to do is create a directory called packages and within that packages directory i'm going to run my mpx create mf app and this is a simple app creator although it also creates express servers so let's give it a try here i'm going to create one called api server and it's going to be an api server it's going to import 8080 as they kind of do and it's just me on the express template so now we've got that if we go take a look over here in packages you can see api server and all it has is a simple index.ts file just creates express it says hello from an api server and then starts up pretty much the most simple api server you can have all right now the next thing we want to do is build our react app so i'm going to do mpx again create mf app and i'll do client here and then this is going to be an application and put it on port 3000 and say that we won't react and we'll do typescript and tailwind okay so now we've got these two directories over here api server and client and what i want to do with this top level is just to yarn and that's going to go and install the dependencies for both of those applications and get us ready to go so there's a few more infrastructural things that i need to do before we get started of course all of this code is available to you on github for free so if you want to just go look there that's fine if you want to play along that's fine too so what the first thing i need to do is set up some ts configs in both the api server and the client and the reason being that i just haven't had this added to that automatic template so we'll just do a tsc init in the api server that gives us a ts config.json with the standard settings and then i'm going to do the same thing over in the react client and then finally there's one small change that i need to make over in ts config for react in particular and that's around jsx so i need to say that we are preserving jsx all right so now that i've done that i'm going to go into our api server and i'm going to install our dependencies that we need to run our trpc server that includes trpc server as well as zod which is a way of defining objects and then cores because we need to use cores to connect between the react client and our server since they're going to run on two different ports now cores doesn't come with typescript types so i'm going to go and add those as well and now we can start building our server woohoo so let's go over into our api server into our index.ts and i'm going to bring in trpc and then with that i'm going to create a router so a router is how you manage your routes and so you can add query routes which allow you to get data you can add mutation routes which allow you to mutate data and send like post requests to the server and then there's subscription routes which allow you to subscribe to data over web sockets so what i want to do is first build a query route just do query here i'll just say it's hello and then i need to provide essentially an implementation so i create an object here we'll say resolve and then i'm just going to turn the data that i want so i'm going to say you know hello world as you would expect and now i need to connect this to express so i'm going to bring in the server express adapter and down here where i have my app i'm going to bring in app.use and then put on the slash trpc route the trpc express create express middleware i'm going to give it my app router and i'm going to give it an empty create context now context is used when you're doing things like authorization you may go and get the authorization from the header and then pass it along so that each route can get the current user information and make sure that they're getting the right data for that user we're not going to do that in this case so i'm just going to keep it at null okay let's actually give this a try so i'm going to go back up to the root directory here and then i'm going to do yarn start and that's actually going to launch both of our applications it's going to launch our react server up here get to see that it's kind of cool but what we're really interested in is our 8080 so what we need to do is try out a route here so where do we put this we put this on localhost 8080 and then under trpc and under hello there you go there it is we've got a result bag the type of data and it's got hello world just like that how easy is that so just to create a query all you've got to do is create a new query here and tell it how you want to resolve really cool so now we want to go and access this query route hello from our react client but i'm not going to be able to do that because the server is going to block connections between port 3000 that has our page and port 8080 which has our api and the reason for that is security and the way to get around it is to go and install cores on your server so i'm going to go and bring in cores here and then down here i'm going to just say app.use and give it course so now this trpc mechanism is named trpc because it's based on typescript and one of the huge values here is that it's end to end typed which means that as i'm over on the client and i'm looking to do the hello query or something like that it's going to tell me what queries are available and what types i need to send and what types i'm going to get back and all of that and so in order to do that we need to expose those types from this api server and the way that we do that is pretty simple we just export the type called app router which is the type of app router an app router maintains all of the types for those routes what the routes are what the routes take as input and what the types output as output and then the last thing we need to do is essentially make this a library so i'm going to go over here to our package.json and say that we have a main and that main is index.ts now we can connect our library of our server to our react app and the way that we do that is again in the console we'll go into packages and this time we're going to go into the client and then we're going to yarn ad and i'm going to make sure to get the exact package name api server here put that in there and then at and then the exact version this is really important and then that's going to link these two up and allow me to go get those types from the api server in our client pretty cool so while we're over here on the client i'm going to go bring in some more dependencies i'm going to bring in trpc client as opposed to server i'm going to bring in the trpc react bindings as well as react query react query is going to be the thing that's actually making the query requests and the mutation request all right let's install those and then i'm going to go back up to my root directory and then do yarn start again and now let's go over and get our client talking to our api server so i'm going to go over here to client go into source and i'm going to create a new file called trpc.ts and in there i'm going to import the create react query hooks helper from trpc react that's the thing that's going to help us create the react query hooks that are specific to our api server and now i want to go bring in that app router we that we exposed from our api server because that's got all the type definitions of what's actually on that api server and then i want to bring all that together by using create react query hooks on our app router so we just give it the types there and we get back this trpc okay now let's go over and take a look at our app.tsx and i'm going to go and return out of here because we're going to be doing some queries and i'm going to call this app content because what we need to do is we need to wrap this app in a react query context so from react query i'm going to bring in the query client and the query client provider i'm just going to create a client up here with a new query client query client manages all of the caching when it comes to react query so now down here i'm going to create a new app and i'm going to return the app the app content wrapped in one of these query client providers but i also need a trpc provider so i'm going to bring in some code for that i'm going to create a trpc client and i need to bring in trpc for that and i'm going to bring in use state so i can hold that and now we have our tc trpc client and so i need to put a trpc provider in there and then give it the client and i also need to give it the react query client so i'm going to give a query client and then give it the client that we built up there all right so now all of the hard stuff really is done we've now connected our trpc client to our trpc server what we need to do is go and make our first query so i'm going to do that up here i'm going to say cons hello equals and then do trpc and then do use query from within trpc so this is like the wrapped react query and then what do i want to call i want to call the hello query just like we created and let's go get the data i'm just going to go and replace this right here with a json.stringify [Music] of our hello.data let's take a look tada hello world awesome how cool is that all right now if we go and change it over here in the api server see hello world two all right does it change no it doesn't change and that's because the server isn't actually refreshing and so what i want to do here is make a slight tweak to our server so that it actually refreshes when we make changes to it and that has nothing really to do with crpc it's just a nice kind of developer experience thing so i'm going to go in here into api server i'm going to add ts node dev in development mode and then over here in the package.json instead of doing ts node i'm going to do ts node dev and that just means that every time i make a change to index.ts it's automatically going to reboot the server all right again let's go back up to the top level directory and then do yarn start and now i get hello world 2 as you'd expect but if i make a change let's see what happens hello world 3 yes perfection awesome okay so now that we've seen how to do a basic query let's do something a bit more interesting let's go base build the basics of a chat mechanism so i'm going to go back over here to our api server and i'm going to define an interface for a chat message which has a user and a message and i'm going to define some basic messages and then we're going to have a query that allows us to get the messages and an add message mutation that allows us to add a message all right so continuing on with our query i'm just going to chain on another query we'll call it get messages and again we're going to resolve and we could just return messages here for sure no problem yeah but what i want to do is i want to show how to use some input so i'm going to bring in zod and with zod i'm going to define the types coming in as the input so let's go here and i'm going to say the input here is a z dot number so we'll say that it's a number and if it's not defined then you'll give it a default value and that default is 10. and what we're going to do with this number is basically just give you the last 10 results unless you specify a number and then i'll give you that many results and this comes in as input here and all i got to do is just say slice and then negative input and that's going to take the last 10 as opposed to the first 10. all right so let's try our get messages over on our client so go back over here to app.ts and then set up hello i'll do get messages and then i'll use get messages data and there we go now we've got our messages whoa cool and let's see if our slicing thing is working by adding on a little extra data so i'll just say that i want the only the last one and awesome we got just the last one that's great okay cool all right so now let me get rid of that because we do actually want i don't know a bunch of these and now we'll create a mutation do that much the same way i'll call that add message and our input in this case is going to be a z object and we'll just resolve with nothing currently just so it doesn't give us all kinds of red lines and in this case what do we have we have a user and a message so we're going to have a user which is a z string and a message which is also a z string cool all right and now that we've got that input i'm just going to add that input to that array and then i'm gonna return the input all right now over on the app side i'm going to go and bring in use mutation for add message and then i'm going to add an on add which calls that mutate this is standard react query stuff gives it the message and gives it the user and then i'll just go and add a button down here it will go and add that message so let's give it a try so now let's add a message hit refresh and there we go now i've got a new message in there from jack hello world and then go and make another one yo world hit refresh hit add message and now we've got yo world as well very cool so now of course we want to go and automatically do that query so we're going to add some options to our on add and just say on success we are going to invalidate the query get messages and now if i add another one let's say yo world again if i hit add message it automatically invalidates the get messages query which forces it to re-query after a successful ad message all right now to make this a little bit nicer let's go and add some state for user and message and then add some input fields for that i'll put these down here and these are just basic input fields type is text value is the whatever it is user we're going to set the user we got some nice tailwind in there and then a placeholder and same sort of thing for message and we can just now replace the message with message and the user with the user and now i've got this and i can say jack hello there from an input hit add message there you go cool and i guess the last thing i would kind of do before leaving this up to you to play with is make this a slightly nicer output i'll just take this messages data say that if it's not there then it's an array and then map it and it will have a row i guess and then within that i'll do a row or give it i don't know message really and then json stringify that cool and now you have kind of a basic chat mechanism you want to go format it and show a different way that's awesome now let's go take a look at the kind of completed next js version of this that uses another outstanding feature of trpc and that's subscriptions okay so here is the completed next.js app it's very similar to what we have before you can do you know hey or hello whatever you want hit return and that automatically sends out something but instead of using that a query mechanism like we had in the original example this one is using subscriptions which means web sockets and means that it's absolutely real time when a new message comes in it gets posted across that websocket and then when there's no new messages nothing happens on that websocket and so what you get is a real-time mechanism without polling which is super cool now if you think i'm super smart or whatever for having built this i'm really not i went over and built out this example by taking the prisma e to e testing eslint auth with next auth websocket and subscription report support based on next js and i basically carved out all of the ede testing eslint off using next off and prisma because i really wanted to boil it down to the basics which was just the websockets and subscription support within nexjs which i thought was pretty interesting so i've actually kind of made this example somewhat worse i guess from a certain point of view but you can always start with this and get all of that great stuff so let's go take a look over at the code now the place that i want to start is over in our server and we can see that we have a get message very similar to what we had before you see we had an ad message pretty much exactly the same as we had before but in this case we have something a little bit new we've got this event emitter down here and when we go and add a new message we're posting essentially an ad message saying hey there's a new message and then we've got this subscription down here which is another thing you can do from the client and when you subscribe you subscribe to a particular event so in this case on ad and then you get back a subscription and this subscription is also watching on that event emitter so it's saying when i get an ad i'm then going to call this function here on add and i get given an emitter which emits from my subscription and then i'm going to send along that data from that subscription and then when the subscription goes away and unsubscribes then i'm going to unsubscribe from that event emitter now that event emitter is a very basic event emitter from node.js and all we're doing is creating that event emitter you just create it you post events to it you can listen to it it's a very nice loose coupling mechanism the only downside is in this case you really only can support one server with this because this is an in-memory event emitter and that means that if i connect to a different server i'm not going to know that you send me a message so what you might need to do is use something like rabbitmq to get these talking together all right let's go over to the client and take a look to see how the client has changed to do this subscription stuff so the first thing we're going to do in our client is get the initial messages just like we did before and then we are going to precede some state that we have those subscribe messages with that data that we got back from the initial query and then we are going to set up that subscription to on ad and when we get a value we're just going to go and add on the new message to all of the existing messages using the set state version where we take the current value and we return a new value and then when it comes to actually adding the message it's exactly the same thing as we had before we have our state we have our add message and then when we see a message and it's big enough then we go and fire off that mutation and then once that's done then we set the current message to empty string so that we are ready to add yet another string to our chat and then the only other thing you need to do when it comes to doing subscriptions is to use web sockets as opposed to hp and to do that you use the trpc client links with ws link and create ws client and then down here in this get ending link we create the websockets client and return the websocket link which we then use within this with trpc as a get ending link so it's actually a little bit complex for sure but the nice thing is that there is an example code that is available to you on github from the really good trpc documentation site all right so now that we know a little bit more about trpc and how to do queries and mutations and set up a server and of course now set up some subscriptions let's talk a little bit about the pros and cons of trpc versus rest graphql and grpc so starting with rest so rest is a vaguely defined standard it's not even actually a standard it is an architectural style that defines how you structure your urls to find entities and then the operations that you can perform on those entities like put post delete and get now most folks don't actually use it like that they go and add on a reporting mechanism for efficiency's sake and that really is an rpc mechanism so i think the pro of rest or what i would call rest plus because people add on top of it this reporting mechanism is that it's familiar but the downside is that it's not a standard that means that the clients aren't standardized and it means that there's a lot of work in setting up the standards for yourself or for your business when it comes to how you structure the rest responses and how you do paging and all of that all right now let's talk about graphql so the huge pro when it comes to graphql is that it very much is a standard the clients are standardized and so that's created a fantastic ecosystem around graphql the downside when it comes to graphql is you have to learn the graphql syntax and i think a lot of folks find that alien and daunting and it's kind of a gating factor to getting into graphql and then there's grpc now grpc is a remote procedure call or rpc mechanism that uses a binary format to talk between the client and the server and so you set up these protos that define the structure of what you're going to send along the line and then you've got code on the client they can format the data into buffers and send them along and it's very very efficient so that's the huge pro when it comes to grpc the downside is also the same that you have a binary mechanism here so you can't actually look at the wire and see as we can to mechanisms like these what the format is that's being transferred around in this case it's basic json with trpc when it comes to grpc it's a binary method so you're going to need special tooling to see the content and to analyze it and there's also some versioning issues there when it comes to different versions of that binary content so let's talk about some pros and cons when it comes to trpc the simplicity of trpc to me is a huge win it feels very native you're not having to learn a new graphql style syntax for this the format going across the wire is json just like we've been used to but there's more structure to it another nice thing is you get that end-to-end typing which is a huge huge win particularly when you use systems like prisma in conjunction with this you're getting typing all the way from the database all the way through to the client and that's just phenomenal but the only con that i can think of right now is that this just isn't something that folks are using in a wide scale as of yet so get out there and try it i think this is really cool stuff and particularly if you're someone who's just getting in to doing the full stack thing this is a fantastic entry point so you should try this out pull down the code here from github take a look at the examples that are on the trpc documentation site and try it out for yourself all right well i hope you've learned a little bit about trpc how to use it in its simple form how do cool stuff like subscriptions how it compares to the other tools that we have today of course if you have any questions or comments be sure to put those in the comments section down below if you liked the video hit that like button if you really liked the video hit the subscribe button and click on that bell and you'll be notified the next time a new blue collar coder comes out
Info
Channel: Jack Herrington
Views: 118,463
Rating: undefined out of 5
Keywords: tRPC, tRPC nextjs, tRPC: Smart and Easy APIs, tRPC/Express API, blue collar coder, jack herrington tRpc, tRPC/Express API + React Client Setup, trpc Server Setup, trpc mutations, tRPC API, tRPC Subscriptions And NextJS, trpc react typescript, react typescript trpc, trpc CORS, trpc route inputs, trpc queries with parameters, trpc typescript, smart and easy API, tRPC Subscriptions, trpc subscriptions, trpc tutorial, trpc nextjs
Id: Lam0cYOEst8
Channel Id: undefined
Length: 25min 28sec (1528 seconds)
Published: Mon Feb 28 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.