How to Build a REST API with Next.js 13

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello and welcome I'm Dave today we will build a rest API with next JS and I'll provide links to all resources in the description below I'll also provide a link for you to join my Discord server where you can discuss web development with other students and you can ask questions that I can answer and receive help from other viewers too I look forward to seeing you there in the last lesson we learned about the new route handlers in nexjs13 they help us build API routes and today we'll build a rest API with nextjs but before we do we should discuss some use cases for an xjs API and we should also discuss what we don't need to use in API for there is no need to use an API route if you're fetching from a server component if you're using a secret API key or a secret URL it will already be hidden on the server it won't be viewable in the client-side code and second if you're not hiding an API key or a secret URL you can also fetched directly from client components without using API routes in your app so likewise a couple of common uses for API routes in an xjs app are to hide secret values like API keys or secret resource URLs and we also previously covered when introducing route handlers that we might also process form data with an API route so as an example of when not to use an API route I am in the previous docs here not the betadocs and we're on the when should I use get static props page well we're not using get static props in next js13 with the betadocs and the new features we're going over instead we're using generate static params and when we've used those that data must be available at build time just as they note here it used to be needed to be available at build time when using gitstatic props and you know if you're building your app well that data won't be available from an API route cause it's being built at the same time so that's going to result in a build error so that's one example of course I already recommended not using API routes for Server components but if somewhere along the way you get confused and attempt to do that and then you're requesting data from an API route that's being built well the server components need that data available at build time to generate those static params now I'm in vs code and let's go ahead and start a new next JS project so I'm going to press Ctrl and the backtick to open the terminal go ahead and clear out everything I had here and then I'm going to use the command that we found in the beta docs before to create a new Next app notice it says create next app at latest and we're going to discuss this because version 13.3 was just released a few days ago now version 13.3 still has a few problems so I'm going to talk about that as we go but I'm going to call this new project next08 just to fit into my series here with the different folders you see in my file tree you can call it rest API or whatever you decide to call it okay after we do that we'll say yes to typescript yes to eslint notice this is new in 13.3 would you like to use Tailwind with this project even though we're not going to use Tailwind today because we're creating a back-end rest API I'm going to say yes just so we can look at those changes then it asks if I want to use the source directory and I'm going to go ahead and say yes to that as well and then default on the import Alias and it will go ahead and create this new project and then I will open up the next08 folder in vs code okay now in vs code I've got my next08 folder open and notice in the package Json we have next 13.3 now we're going to make an adjustment here because there's a small problem they have a bug currently with the delete route Handler and I filed an issue for that already on GitHub and hopefully they will fix that soon but currently if we await the request.json it throws an error and it works in 13.2.4 which was the previous version so I'm just going to go back to that now if you're watching this in the future hopefully you're on a newer version than even 13.3 and you won't have that problem so you might try that out before you roll back to a different version I'm going to press Ctrl and backtick to once again open that terminal window I'm just going to type npm I and then next at 13.2.4 and this will roll us back to that previous version where the delete route Handler is still working as expected with that request.json so now I'll close the terminal and we can see that I'm once again for this tutorial using 13.2.4 now just a side note on that install we did of 13.3 where it added Tailwind notice we didn't have to manually do any of that we already have a Tailwind config file and then if we go into the source directory and look at our Global CSS it already adds the three lines we were manually adding before so that's just a nice addition that they added in 13.3 where we can choose to add Tailwind basically effortlessly to our project right at the beginning when we created now we're going to create five rest API endpoints today in xjs and we're going to pretend we're using these routes to hide a secret URL resource and even send an API key with any request that's not a get request but first let's discuss environment variables okay now I'm back in the stable next JS docs not the beta docs and it says they get the environment variable values from dot env.local that's where it will load them and we will format them like this so environment variable name equals and then value notice there's no quotes here so that's how we will put them in our DOT env.local file also note that after we create this file we will want to add it to our DOT get ignore file if it's not all already in there but we'll take a look because I think we already have a DOT get ignore file and of course that keeps this file from being loaded into GitHub with your repository because you don't want to share this information with the rest of the world not even in your GitHub repository and now I'm back in the beta docs under static route handlers and I just want to show an example here of where they're providing an API key in the headers of their request so this is how we will access that data from that dot env.local file we'll say process.env dot and then the name of the variable we gave it not the value but the variable and then it will put the value in our code where it's needed now we're back in vs code we do have a git ignore file so I'll click that and as we look at this file this lists out any pattern or extension or exact file for that matter that we do not want included in our GitHub repository and here it has local EnV files and we can see dot EnV than an asterisk dot local so you could even have something after this or more than one EnV file but we can just create a DOT env.local and put our value in there for today so let's do that by creating a new file here at this top level of the application call this Dot env.local and then we're just going to say data underscore API underscore key which I believe was the same variable that we saw in the docs there and we're just making one up and you can put anything you want here it's usually a long random kind of looking value but what I'm going to put is Dave Gray teaches code and I'll just have that be the value because we're just going to log this to the console we just want to make sure we know how to do it and send it in those requests now let's begin creating that backend API inside of our API folder that's inside of the app folder so I will highlight that we have the example hello folder or directory if you will let's highlight the API folder and let's create a new one here and let's call this to Do's because we're just going to get the example to Do's from Json placeholder and pretend it is a secret resource now inside of this to Do's directory let's create a new route file so we'll need route dot TS now before we begin building the route let's go ahead and create our types dot d dot TS file that we're going to use so I need that in this top level once I'm down here I'll just type types.d.ts and inside of here we're just going to have one type today and it is a to do set this equal to a type that has a user D that is a number then we'll have an ID and that's a number a title that is a string and then a completed and this is a Boolean and now we're ready to go back to our route and we'll start adding some code here and we'll create the first route which will be the get route but we'll start with the import and we need the next response that's going to come from next slash server after that we'll go ahead and Define our data source that we can use in each of the handlers so I'll say const let's call this data underscore Source underscore URL and let's set this equal to that Json placeholder URL I'll press alt Z so it wraps down but you can see jsonplaceholder.typical.com to do's and this will give us 200 to Do's that we can request and of course send all types of crud requests too so create read update delete so now before I begin the first route Handler you might want to use this tutorial as a challenge so maybe you want to pause here and try to create the route Handler before you see how I create it so this will be the get request where we will request all of the to Do's now you can go ahead and do that first if you want to or just follow along with me we'll start with export once I get lowercase async function and it is a git Handler now we're not going to send the API key with any git request so here we can just get our response right away once again lowercase and I'll just call it res for response that's going to be a weight Fetch and we're going to fetch the data source URL that we have above and it's just a simple get request to to do so we don't need to add anything there and after that let's define our to do's and it is a type of to do that is an array of to do's and we'll set this equal to a weight and once again response then Json so we get that Json response there and then we can return next response dot Json and just pass in the to do's and that should finish out our simple get request route Handler let's go ahead and test this Handler so we need to start our application with npm run Dev and once it's running we're going to use well basically anything we want I'm going to use thunderclient you could use Postman if you're more comfortable with that or there are some other extensions that also allow you to issue requests we'll be looking at localhost 3000 and then slash API slash to Do's so I'll go ahead and close the terminal I'm going to use thunderclient which I have right here if you don't have the ThunderClan extension and want to get it you can search for it in your extensions it's two words under client there we go and it looks like this you can see mine's already installed and enabled good to go so you'll see how I use that I'm going to choose thunderclient here from my bar and then I can issue different requests I'll create a new request here this will be localhost 3000 then slash API slash to do's and now we can just send the request and I have an error because I left the s in the HTTP I need to remove that because here on our local host and if we look back at our terminal we'll see it is just HTTP and not https so we'll close that out again and hopefully I won't make that mistake again but it's very easy to do but here we got the 200 response and we have all of the to Do's we've received you could scroll through all 200 of those if you want I can even drag this up a little bit higher if we want to and of course with the other requests we'll be sending a a body as well so we might need a little room for that but that works as expected so our get route Handler is good to go okay let's go back to our route TS file and now we'll go ahead and create the delete route I'm going to scroll for just a little room here and now at the top we'll type export async function and we'll use the delete route now this will receive the a request and it is a type request now we need to receive the ID in this route so we know which to do to delete so I will destructure the ID that is coming in and this is going to be from a partial to do type we'll set this equal to a weight request.json now just to note here this is the portion that currently just the very new version 13.3 is having an issue with so this is why I rolled back to 13.2.4 right now if you're watching this in the future hopefully there is no issue but if you're watching this around the time this tutorial was just created you may need to roll back to 13.2.4 for this portion of the code to work in the delete route Handler so now we need to check to see if we received an ID or not so here we'll say not const I'm sorry but if we do not have an ID then let's return a next response dot Json just with a message that the ID is required so we'll say message and here we'll have to do ID required and there I am using single and double quotes let me just select that so I'm consistent and switch those to double as well so that's the message if that ID is not supplied with the request but otherwise we can await fetch once again and here let's create a template literal and we'll pass in that data underscore Source underscore URL after this the way the API works that we are requesting from needs it needs to receive that ID value right here inside of the URL so we'll put that but then we also need to put some options with the fetch so here we'll have method and that is delete after that we need headers and we'll be using these on all of the requests that are not get requests here we'll have the content Dash type and we'll say this is application slash Json and after that we'll have our AP Pi key now this is not really necessary for the Json placeholder API that we're requesting from but this is just an example if we needed to send it because this API won't complain when we do send it now I'm setting it equal to API key but we haven't defined that yet so let's do that at the very top of our code where we defined our data source URL as well we'll say const once again lowercase Now API key and this is going to equal well let's say it is a string first too because we want to set the type and this is going to equal process.env Dot data underscore API underscore key that we set and now notice we still have a problem with typescript because it says string Union type here with undefined can't be assigned to string so what we want to do here is an assertion so I'm going to say as string and now this will be okay with the API key now let's scroll back down and finish our delete route Handler so we have the await Fetch and after that we don't need to do much more so we're just going to return nextresponse dot Json and here we can put in a message once again because we won't really get anything back from the API when it deletes something but here we can just say again a template literal and I'll say to do then we'll pass in the ID value and deleted and I can tell by the red in the file name we still have an error and when I look over here where I scroll I can see that dot is right here and there is the error I did not put a comma before I put in the options with the fetch so you need to have the URL comma and then the fetch options object so now let's save this route and we want to make another new request to test this out so here I'm going to switch the method to delete and now we need to pass some Json so we can't just go to slat well this is actually going to just go to our API slash to Do's once again because it's just the delete Handler for that but when it gets sent to the actual Json placeholder here in our route it needs that ID so we need to send the ID in the body because that's how we're destructuring it here from the request.json so now we'll go to the body I need to drag this down and let's just send an ID to delete so this needs to be valid Json here and we'll just say delete to do number five you can see that X went away over here once I had valid Json there the x is back saying this is not valid now when I put that in there it is valid so we're sending a delete request with Json here in the body of id5 and it's going to our API route in our next JS app which will then go ahead and make the request to that data source URL that is our hidden resource so now let's send this request and we've got our message back message is to do five was deleted now of course since we're working with this Json placeholder site it doesn't really delete the to-do's but we do get the success for the status and it gives the appropriate response for each crud method create read update and delete and so on so we know we've got that and now we are ready to build our post request route Handler so I'm going to highlight all of this from line 15 down to 29 use shift alt in the down arrow to copy it down because there are a few differences from post and delete but we can certainly use this to start out without typing everything all over so I'm going to choose delete here and switch that to post it's going to once again receive the request after that it's not just getting an ID as a matter of fact it doesn't really need to get the ID that will be assigned because it's a new post it does need to receive the user ID it also needs the title of the to do and now once again we need to check to see if we received this data so here we can say if no user ID or if no title and then our message isn't quite right so instead of to do ID required we can just say missing required data and now we're going to send a fetch again but we want to get the response so let's say const res equals and we'll await the fetch now this resource the data source URL is the same but we do not need to append an ID at the end so I'll just remove all of the template literal information and we'll just send that directly to the data source URL and now the method needs to be switched to post and after that we'll have the exact same headers but now we're also going to have a body that we send here so the body will have Json Dot stringify and we're going to stringify the data that we are sending so we're going to send user ID and we're going to send title and we'll also send completed faults because every new post would be false it would not be completed yet okay and now with that new response we've got we can say const new to do and it is the type to do set this equal to awaitresponse.json once again and now our message just needs to be changed here and what we want to send back is that new to do that was created so we can just put that in the response and now we're once again ready to try out our route Handler and this is a post so let's go to new request instead of an ID we're sending a user ID but then we're also going to send a title and I'll just have something simple here like make the coffee Okay so we've got what's required here user ID and title being sent in the body and once again this is going to go to our next JS back end and API to Do's we just need to pick the appropriate HTTP method which is post and then our route Handler will take it from there so let's go ahead and send this and we've got a 200 it was successful and we received the new to do in return and you can see it was ID 201 so that means it was added to the 200 that were there now of course Json placeholder doesn't really add the to do so next time we would send a new one it would also have the ID 201 it doesn't really add to its data but it gives you the success like it did so I can send it again and we still get 201 back let's go back to our route TS file and now we're ready to create the fourth route and the final one that we'll add to this route TS file and this is the put request route Handler so I'm going to go ahead and highlight all of the post down here to line 34 press shift and click and now do shift alt and the down arrow to just copy that full post request down because put is very similar now once I'm here I'm going to change the post to put and the put request needs to receive everything about the to do so we're going to have an an ID a user ID a title I'll put the ID in between in the same order that we did the type I believe and after that we're also going to have completed so that makes this not a partial to do but the full to do type right here now we need to add some more checks for missing data so we can check to see if the ID is missing as well so we've checked the first three here now we can't check the completed in the same way because if you just put an exclamation mark with Boolean when it would be false it would become true and so on so what we need to do here is you could really check to see if it is the type of Boolean and that's what I'm going to do you might have another check in mind as well but that's what I'll do here so type of completed we'll just make sure it's either true or false so if it's not equal to Boolean we have a problem now the message missing required data is fine so let's scroll down here let's switch the method to put once again we'll keep the same headers where we're sending our fake API key and now we're going to stringify what we're sending as well so we're going to send user ID title and completed and I'm going to change this to just say it's completed whatever value we receive will be what will be updated so we'll just leave it as completed now notice we're not sending the ID because we need that back in the URL once again like we did in the delete request so I'm going to copy it down here the data source URL and that ID needs to be right at the end so Json placeholder knows which to do to update so I'm going to just select data source URL and change it to our template literal that includes the ID at the end of the URL now at the very bottom while this would work it just doesn't seem right to call it new to do because it is the updated to do and then we'll just copy that and that will be the response as well so it will just send back the to-do that was updated with the new information so now let's once again go test our route so from here we're sending a put request it's the put HTTP method once again to the same URL for our next JS API that will then handle it in the route Handler so in the body now we don't just need user ID and title we need to go ahead and add the ID as well so we'll say post ID 5 is fine and then we need to send completed which has to be either true or false so we'll say completed and we'll say this is true and that's not going to work so we need lowercase true I was typing uppercase true because I was just working python as well and that's what that's what it likes so once again back to JavaScript typing true and lowercase okay we're ready to send our put request that will update the to do with the ID of five let's see what we get and it was okay user ID 5 title make the coffee completed true and the ID of the to do is five once again Json placeholder doesn't really update the data that it has but it sends us a response as if it did now if you wanted with each of these handlers you could also go through and test to make sure that our messages for when it doesn't receive data that it's expecting works so here instead of sending Boolean data I'm just sending my name when I send that we get that missing required data which it is missing I guess but we could get more specific if we broke that down into a statement for each one instead of one statement that handles all of it but either way I believe you understand the concept of how to do that we're now ready to create our last route Handler but it doesn't go in this route TS file so let's go back to the file tree and take a look at what we have here and we're inside of the to Do's route and then we go to the route.ts file but we could also create a dynamic Dynamic route in here so I'll select that to Do's directory and create another directory that has a dynamic route based on the ID of the to do and then inside of this directory I'm going to create another route.ts file now this file is going to start much the same as our other route so I'm just going to go to the top here and copy everything from the top line all the way through our git Handler so I'll just Ctrl C come over to this new file and Ctrl V to paste it in now we're not going to need the API key so I can delete that this get request is actually going to need the request so we're going to put request here and have it be type request that's because we need to get the ID from the request because it's going to be in the URL for this Dynamic route so here I'm going to say const ID and I'm going to set it equal to the request.url now this would be the full URL as string and then I can say dot slice and I'm going to slice the request dot URL and then use dot last index of and I'm going to look for that last slash that is in the URL because after that slash is actually where the ID would be but with the slice method we're telling it where to start not just where to end so we don't have to put in an ending we just need to tell it where to start is what I guess I'm trying to say so I don't want the slash I just want to go plus one and have it start and get everything after that whether it's the to do ID number 200 or the to do ID number one so it could have as many digits after that as it wants and we would get all of those we just don't want the slash okay now that we have the ID we need to add that once again to our data source URL so I could go back to where we've typed that just so I don't have a typo and we can get that from one of these other methods that used it so here is our template literal that has the data source URL and the ID so I'll control C to copy that come back back here and I'll replace this data source URL with the full template literal and now we're just going to get one to do back because we're only requesting one so I'll make this a to do and instead of an array of to-do's it's just one to do so that's what we expect there now we need to just check to see if we do not have a to do if we don't receive one back so let's say if no to do dot ID that's what we'll check to make sure we have it to do we'll say return nextresponse dot Json and we can provide a message here so I'll say message and this will be well let's put that there we'll just say ID not found or we could say to do not found do not found and that would work fine I'll press alt Z to wrap that down and then if we do have a to do we'll reach this final return here at the bottom and we'll just return that single to do so now we're ready to test this route Handler out and it's going to have a different URL it will be basically the same URL as before where we look at API to Do's but then we'll go ahead and add the to do ID at the end of the URL for our next JS app so when we send this request we'll have API to do's and I'm going to request say to do number 199. this will be a get request let's go ahead and send that request and we've got 199 back from the Json placeholder website Okay so we've created a very simple API where we're simulating relaying information from a third-party secret resource or pretending to get data from a database and of course we're practicing sending an API key as well which by the way you can console log that API key to get that value in your console that we would see here in the terminal for next JS that would be the console where you would see it but you can take the next step and do either of these by accessing another third-party API that you really do have an API key for say you're getting a weather information for a weather app or something like that you want to hide your API key that would be perfect for this or you just want to hide the actual resource that you're using in your app and of course by keeping that resource URL on the server that will never be sent to the client and your users couldn't find that in your code so next JS API route handlers can be very useful well and then the next lesson we're going to go over middleware that can also be very useful remember to keep striving for Progress over Perfection and a little progress every day will go a very long way please give this video a like if it's helped you and thank you for watching and subscribing you're helping my channel grow have a great day and let's write more code together very soon
Info
Channel: Dave Gray
Views: 32,450
Rating: undefined out of 5
Keywords: how to build a rest api with next.js 13, rest api with next js, rest api, next.js, nextjs, next js, how to build a rest api, next.js rest api, nextjs rest api, next js rest api, api endpoints, next.js route handlers, nextjs route handlers, next js route handlers, next.js api endpoints, nextjs api endpoints, next js api endpoints, dynamic api routes, next.js dynamic api routes, nextjs dynamic api routes, next js dynamic api routes, api routes, build a rest api, next.js 13, js
Id: -MFiza7ZRzs
Channel Id: undefined
Length: 31min 17sec (1877 seconds)
Published: Tue Apr 11 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.