tRPC + NextJS App Router = Simple Typesafe APIs

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
ever since the next js13 app router with react server components was released people have been asking about how to use trpc with that trpc is a fantastic type-safe remote procedure call system that worked really well with the pages router in particular people used the T3 application in the stack which was based on trbc and pages but we really didn't have any patterns for how to work with the app writer now we do I'm going to show you that in this video we're going to go build a simple to-do list application that uses trpc to connect to drizzle for an orm to connect to SQL Lite and we'll do a simple to-do list yeah I know all right and of course in the meantime if you are interested in next.js be sure to check out pronextjs.dev that's a course that I'm working on it's not released yet but you can sign up for a newsletter and you'll get tips and tricks and all kinds of great stuff and you'll also be notified when that corset available so go check it out today all right let's get right into our to-do list using trpc on the app router with Drizzle let's get right into it foreign [Music] let's start off with a boilerplate next.js13 application using tailwind and the source directory of course using the app router and the first thing we're going to do is just Pare down this home page we'll just replace it with a blank page currently and then we'll start getting into your PC so the first thing we need to do is add some libraries now in this setup our next JS server is going to serve a dual role it'll serve our pages off of Slash and that'll it will also serve the trpc endpoint off of Slash API slash grpc and then the trpc verb so first off we need to install the package that allows us to act as a server so we'll bring in the trpc server package we're also of course going to make queries and that makes us a client so we need to bring in all the trpc client code we are going to be using tan Stacks react query on top of trpc so that's why we're also going to be installing trbc react query as well as tan stack react query as well as the trpc client so the first thing you need to do when you create a trpc server is initialize that trpc server so all of the server code is going to go in the server directory under Source let's go and create our trpc file inside of source server so to do that I'm going to do a fun trick for you I'm going to do server slash trpc .ts and that's going to create the server directory for me if you didn't know that little shortcut there's one for you right there so here we just initialize a trbc server and we get back from that the router and also public procedure now we're going to go make our trpc router that's going to have our procedures on it I'm going to put that in index.ts so we create our instance of an app router using that router that we just created over in trpc and then we use that to add any functions we want in this case we're going to add the get to Do's function and it's just going to turn 10 20 30. some numbers we just want to see how this is actually going to work from the client to the trpc endpoint so let's hit save now we actually need to connect it into the app writer itself to do that we need to create a route inside of the app directory that's going to Route requests to that trpc instance to do that I'm going to create a new file in API grpc and then the brackets trpc directory that's going to capture whatever the verb is in this case get to do's and it's going to set that as one of the route parameters and then we create a route Handler to do that we use route.ts and again using these slashes is going to give us all of those directories all right so this is the part where you actually see the big difference between the pages router implementation and the app writer implementation in the pages writer there's actually a already set up adapter specific to nexjs which is customized for pages that doesn't work for the app router for the app router we use the fetch adapter which just happens to have the exact same signatures that we need for the route handlers in next.js with the app router it's really cool and it actually works and you'll never need to change this particular piece of code from here on out to just add more functions the only thing you're going to need to do is just add more items into the index all right so let's hit save on that all right so now let's try it we can actually call get to Do's right out of the browser so let's bring it up and this is what our app currently looks like of course we want to go over to API trpc and then get to do's and just like that we have our data so the next thing we want to do is make this request using react query from the client so let's go get that set up so the first thing we're going to do is create a trpc client to do that I'm going to create a new directory called underscore trpc and then within that client.ts now I used underscore trpc because any directory starting with underscore is ignored by the app router in terms of routing so now we're going to create our trpc react client we do that by getting the app router types from the server and then we create our trpc react using the react query adapter library now we do command K command I on app router we see that we have get to Do's as a type coming off of that server so that's how it's actually routing the types all the way from your server code to your client code now react query needs a provider so we need to go and create a query client as well as a provider so I'm going to go do that in the provider.tsx file in trpc now in here we're going to create a react query client as well as a trpc client and then we're going to vend those down to any included children so let's go and use this provider in our layout so bring in our provider and then we'll wrap our children in that provider now we're going to create a to-do list that is an interactive thing we're going to be using react query from the client that means we need to create a client component so let's go create a new directory called components that has a to-do list in it so we'll start off with a to-do list client component now let's go and make that request to get to do's to do that we start with trpc and then we can see that we have all of the functions in this case just get to Do's listed already on that trpc object and then what's in that well we get a whole bunch of stuff we get use Query and that's the react query use Query hook but automatically targeted at our trpc backend and now let's just Json stringify the data that we get back and let's bring it into our page and there we go there's the 10 20 30 data that we had over in our trpc endpoint so if I change that to 40 50. add some more come back there and because we are basically refreshing the server code that's going to do a hot module reload on the client and we get our new data how cool is that now to make this example more practical I want to connect us to a database now to do that really easily you can use a couple of different things you could use Prisma or you could use drizzle so we're going to try out drizzle with sqlite and we'll see how it goes so the first thing we need to do is add drizzle to our project to do that we're bringing in drizzle orm and then also as equal light adapter called better sqlite3 Y3 doesn't have types so we need to bring in the typescript types for those and now we need to specify our schema what is our database actually going to hold so I'm going to create a new file called DB schema.ts so we had a directory called dbe and then within that schema and then we're just going to say we have to do's and we're going to give it the fields in this case IDE is just a primary key and then content is the content of the to do and then done is an integer in this case that's zero if it's not done and one if it is done it's an integer at this point because sqlite doesn't have a Boolean if you can believe that now we need to tell drizzle where all this stuff is so we need to create a drizzle configuration file so over the top level I'll create a drizzle.config.ts now our configuration uses drizzle kit because this drizzle kit is what you actually use to do migrations so let's go and add that otherwise we're just telling you where our database is what the driver is and what the credentials are now with Drizzle kit we need to go and create our first migration so I'm going to do drizzle kit generate SQL Lite and that's going to give us this error about es5 turns out the TS config that comes off the shelf with app router is targeting es5 If we Just Bounce out the es6 we can get it to build our migration all right so it's built one table migration for us we can see that over in the drizzle directory in our migration has gone and created our to-do's so now we've got our database all set up now we just need to connect it to our trpc to do that we go over to our server and then into index.ts and this is where all the action is going to happen now so we need to bring in our drizzle stuff so we're going to bring in drizzle we're going to bring in migrate migrate's going to run every time we start up and automatically migrate the database if it's needed and then we bring in our database driver from better sqlite then we need to bring in our to-do's object from our schema that's what we're going to use to actually make all the requests next we need to set up our sqlite database point it at our database and then create our database drizzle object and then we migrate using that database and the directory that we just created so now we can replace this hard-coded data with a query of our database now to do that all we do is we just say that we want to select off that database from the to-do's table and we want all of them but you can add any kind of additional where Clauses as you want it's a standard kind of orm similar to what you'd see in Prisma all right so what we're going to get back now is an empty database so we need a way to add a to-do item to the database that means adding another remote procedure call so in order to do that we need to have some way to validate the input for that we're going to use Zod so we've added Zod so he adds on to our project and then we import it in this file and now we can say that we have a new function called add to do it's going to be a public procedure but now we get to Define what its inputs are we say input and now we'll just say that we want a string so Z dot string that's all you need for this we only need the content so we just need a string and it's going to be a type of mutation as opposed to a query and so we'll have an async function that takes some options and then so we'll call db.insert that's a promise we want to await that where do we want to insert well we want to insert into to-do's then we need to give it its values in this case the content which we're going to get from Ops input and then done we're going to set to zero and then we're just going to run it and we'll say it's always going to work so return true all right cool now we got our add to do endpoint let's go and try it out to do that we need to have an input as well as a button so we're gonna have some state so let's bring in use state the state is going to be the content so let's track that and down here below this div we'll have an input field as well as a button that's going to make the call to that add to do so now to get that ad to do we go back to our trpc and of course now we got add to do ta-da and we know it's mutation so it's only going to give us a use mutation how cool is that now we go and check to see if it's an empty string and if it's not an empty string then we call that mutate function on that add to all right the page is up and running we're getting an empty array at the top that means that it's made the request that's really good so let's try it out let's add in first to do hit add to do and now if we refresh we see that we get the updated data so how do we force that refresh every time well we do that by going over into use mutation and then look for the unsettled event and when everything is settled then we do a refetch on get to Do's so we do get to do's refetch let's try it again and there you go how cool is that all right let's make this look nice with Tailwind we'll go and add some tail and styling ah looks pretty nice okay cool I'm getting kind of tired of this backdrop so I'm just going to remove that and now let's format up these to Do's nice and pretty we'll get rid of our Jason stringify and we'll just iterate over that data that we get back using a map and we'll create inputs for each one let's have a look first all right looks pretty good now I do want to go over one thing here so if we look at get to Do's data we can see that we actually get all of the typing and this is where the big advantage of trpc is so let's take an example where I didn't use trpc to call that same endpoint so if we have a use effect which might be the way that you would make that fetch if you didn't have trpc what you get back from typing on to-do's here is going to be just any because we have no idea what's coming back from the server that's the huge win with trpc trpc is preserving the types all the way from the schema all the way through drizzle through those remote procedure calls all the way up into the client on both queries and mutations and it's doing it really really simply all right now we have a checkbox on these and we want to be able to actually set that done case so let's go and create a remote procedure call for that to do that we're going to add a set done remote procedure call Now set down is going to take as input and object that object's going to have an ID on it which one do you want me to change and then the new done value and then it's going to call the update on the orm but we do need to bring in EQ here so bring that in from the drizzle orm all right looking pretty good so now we need to go over to our to-do list and we need to bring in our set done or what do we have here what we have set done how cool is that so fast and then down in our input we're just going to have an on change that says whatever it was just flip it so let's hit save and there we go and we can hit refresh and you'll see the one last thing I actually want to cover which is you see that flash right if I do refresh it doesn't happen instantaneously in fact if we look at the page Source we can see that there is nothing in the page source for our to-do list all of the requests are coming off of the client so if you want to use this system with server-side rendering well what do you do well it turns out that's actually pretty easy too so let's jump into that and see how that goes to do that we're going to start with a server client over in our trpc directory it's basically like the original client but in this case we're going to do create caller and this is just a basic trpc system that anything can use not react in particular so here we go let's go and use this to make HTTP requests over to our endpoint but doing a type Safe Way so go back into our page which is where we want to do that fetch we'll bring in our server client we'll make this an async function and then we'll get our to-do's so how do we do that what we call a server client and we do get to do's of course that is a promise so it's a weight then and let's see when we get back well we get back exactly what we want totally typesafe now let's pass these as the initial to Do's to our to-do list of course it doesn't understand what that is so let's go and add that initial to Do's prompt to our to-do list so we'll say we have initial to do's and we'll type it but what do we type it as well let's go get the return from the request that we just made so we take the return type of the get to Do's function coming off of that server client but is that right well let's do a command K command I what we're getting is the right data but it's actually wrapped in a promise so how do we unwrap the promise because we've already got that data we don't have a promise for it so we'll use awaited for that and now if we look at the typing we have exactly the type that we want and if we go to page no problems looks good okay so what do we do with this initial to Do's well we use it as the initial data on our use Query so our use Query takes the parameters that you would send to the query in this case it's just undefined and then it takes a set of options so we're going to start with initial data which is going to be our initial to do's let's hit save try it out and now there's no Flicker and if we go take a look at the page source we can see that the data has been rendered into tags during server-side rendering which means that we have a fully server-side rendering system awesome I have just one more thought though let's go take a look at the network inspector and hit refresh and we can see that we're actually making that call again on the client when we are mounted so we can actually avoid that because we don't really need to do that by adding on two additional parameters to our use Query refetch on Mount and refetch on reconnect and now if we go back to the network panel we can see that we don't make that secondary request from the client because we already have that data but if we add another to do we do end up making that secondary request to get the new data all right well I hope you enjoyed this look into how to use trpc within the app router I'm certainly excited about it I love trpc and I'm also getting to love this drizzle orm it's pretty cool too of course I'd love to hear from you any comments that you may have be sure to put that in the comments section right down below and if you like this video do me a favor and hit that like button if you really like the video hit the Subscribe button click on that Bell and of course head on over to pronxtjs.dev and sign up for that newsletter to get all of the hints and tips and tricks and get the news for when that course comes out
Info
Channel: Jack Herrington
Views: 59,069
Rating: undefined out of 5
Keywords: tRPC, tRPC nextjs, tRPC: Smart and Easy APIs, blue collar coder, jack herrington tRpc, trpc Server Setup, trpc mutations, tRPC API, tRPC Subscriptions And NextJS, trpc react typescript, react typescript trpc, trpc route inputs, trpc typescript, tRPC Subscriptions, trpc tutorial, trpc nextjs, next.js 13, next js 13, nextjs, next js, next.js, nextjs react, nextjs typescript, next js typescript, react, reactjs, react.js, nextjs 13.4, trpc app router nextjs, trpc app router
Id: qCLV0Iaq9zU
Channel Id: undefined
Length: 19min 17sec (1157 seconds)
Published: Mon Aug 21 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.