Next.js Fundamentals, v4

API Routes

Scott Moss
Superfilter AI
Next.js Fundamentals, v4

Lesson Description

The "API Routes" Lesson is part of the full, Next.js Fundamentals, v4 course featured in this preview video. Here's what you'd learn in this lesson:

Scott explains that API routes in Next.js are designed to execute in a serverless environment and follow web standards. Scott also mentions that API routes can be useful for handling webhooks or creating a developer API, but they are not always necessary for basic CRUD operations within an app.

Preview
Close

Transcript from the "API Routes" Lesson

[00:00:00]
>> Scott Moss: Now that we got caching out of the way, let's talk about API routes, the thing that I said you'll probably never need ever again [LAUGH]. Because as you can see, we just built a full CRUD app without making one API route whatsoever. It's pretty amazing. But there still are use cases for API routes, not even just externally, but internally as well.

[00:00:22]
Use cases for making API routes for the app that you're actually building. There are still some use cases, for sure. They're just not as wide as they used to be cuz you can just use server actions for a lot of stuff. But nonetheless, Next.js makes building API routes super easy.

[00:00:40]
They are designed to execute in a serverless environment. Vercel has serverless, all its competitors have serverless. Serverless is kind of a thing at this point, so they just built a framework around that. And recently, since next year is 13, they changed the syntax of it. So it follows the web standards of kinda like the edge syntax for making requests.

[00:01:04]
So it follows the web standards. So it really is super simple. They don't even do anything special in here. I mean, there are some things that are really cool, but as far as what's exposed to you, it's very simple. It very much follows the spec of what is out there, it's really good.

[00:01:23]
So let's talk about it. So API routes, if you don't know what they are, HTTP routes that you can hit that usually send back some data, right? So really, really easy to make these. Let's just go ahead and dive. I have tons and tons and tons of notes on all this stuff.

[00:01:40]
And we'll definitely talk about it. But I think it's just so much easier to just go into here and start playing around with this. And then we'll make some API routes. So you can follow along if you want here. But this is just gonna be me demonstrating API stuff.

[00:01:52]
And then I'll let you know when we're actually gonna make the APROs that we need for our app. So the first thing to know is, where do you make an API route? Well, in our case, we're using the app directory. We're not using source. So we go into app.

[00:02:04]
And we have to have a folder called API inside of app, it has to be an app. If it is not an app, it will not get picked up as an API route. So I'm gonna make a new folder, gonna call it API, even get a suite icon for it.

[00:02:20]
It's very similar to pages. So with pages, we have to have a directory, that's the path name, and then we have to have a page.tsx. Routes are very similar. Yeah, API routes are very similar, you can have a path name. So in this case, let's just say I'll make one called user, right, that's gonna be the path name.

[00:02:40]
And then if I want to make a route here, I'll make a file, instead of calling it page, I'll call it route. And this will make a route with the path of /api/user. It's always /api/user. Right, so for people who are versioning their APIs, you could do a v1, right?

[00:03:09]
So it's /api/v1, and now you've versioned it. So if you're doing graphql, you could do a graphql, and then put your route in here, very simple. So what does the actual route look like? How do you determine what verb or whatever? So one route file, you can create as many HTTP verb that you want in the one route file.

[00:03:43]
So what does that look like? It's all about the exports. So if I export GET, this is going to be a handler. For a GET request, that is for /api/user, right? If I do a export for a POST, same thing. Options, put, delete, patch, whatever you want. That's it, you just export that variable or that function, and that's what's gonna run.

[00:04:19]
What you get as arguments, this is the thing that's focusing on the spec is you get the request. And this will be a NextRequest. It's kind of a wrapped request, but let's just say NextRequest for now. So you get this request object here. Let's just do a hello world thing.

[00:04:47]
So I'm gonna return. I could actually just return a response, which is native to web standards. But I'll use a helper from next/server, that makes it easy to do some stuff. And I'll say, NextResponse.JSON. That won't have to add the headers and do all that stuff. So I can say data: message: hello.

[00:05:17]
So I'm just doing a GET request to /api/user. It's immediately going to respond back with some JSON, with a data object, and a message of hello. So now I need to test this. I'm going to use httpy. So httpy is a really cool postman like client. They actually started as just a CLI.

[00:05:45]
I've taught a lot of courses here where I just use their CLI and it works really good. But now they have a GUI. And honestly, this was the only one that I could find where I don't have to make an account or pay. I couldn't find any other one.

[00:05:56]
Postman, Insomnia, which there's an issue on Insomnia talking about its malware. Don't use it, [LAUGH] which is funny. But this was the only one that I could use without an account, even though they do have a paid offering. So this is httpy. You can use whatever you want.

[00:06:10]
You can use curl, just to test these endpoints, whatever you wanna do. But let's make a request to /api/user. I don't need any authorization stuff right now, so we can just ignore this, it doesn't really matter. Let me make sure I have this running. Okay, and then let's issue a request, 404.

[00:06:41]
>> Speaker 2: User, you've pluralized.
>> Scott Moss: It's user. Okay, there we go, cool. So got back 200, there's my JSON object message. Super simple, it's literally the simplest server you'll ever make in your life.
>> Speaker 3: Quick question.
>> Scott Moss: Yes.
>> Speaker 3: So you're hitting the localhost 3000, which is also the server for the client.

[00:07:03]
So internally, Next.js is doing a proxy to the server internally, or?
>> Scott Moss: Well, yeah, internally, cuz it's local development and I don't have actual serverless containers and VMs. What it's actually doing is, it is spinning up probably an express JS server, in which it's just mounting the API on /api.

[00:07:25]
So locally, it's doing that. When you deploy this somewhere, the way it works with serverless is, a lot of serverless functions can be triggered off of some event. The most popular event is a incoming request. So the way it works when you deploy it is, your request will get captured by some API gateway on AWS or something like that.

[00:07:46]
And what that does is it maps to some code that you deployed there. It'll go grab your code from cold storage or S3 or wherever it is, whatever bucket, if it's not warmed up, unzip it, load it into memory, and then execute your code. Right, and that's essentially what serverless is doing.

[00:08:07]
Cool, any questions on that, yes?
>> Speaker 2: Can you just use your dev tools to do the same thing, or?
>> Scott Moss: Yeah, yeah, you could use whatever you want to access the, wait, are you talking about for playing around with API, or you talk about-
>> Speaker 2: If you hit that URL and you went to the network and you found that user file inside all the network files that came in, would that be a good way to test it as well?

[00:08:36]
>> Scott Moss: Well, so this a server side route, and it won't get bundled with your client. So this won't show up in the browser as a code that the browser is seeing, cuz this is purely server side. So Next.js at its core is a full stack app. I like to say hybrid cuz server actions, it's kind of both at the same time, but now we're fully on the server side.

[00:08:59]
This has absolutely nothing to do with the client. You can share code, and that code has to work in the browser and in node. But yeah, you won't see any of this stuff on the client side. In fact, you could just spin up a Next.js app, have no pages, and only have API routes, and just deploy that, and now you have an API, yeah.

[00:09:25]
>> Speaker 3: Then sucking in data on the client would be similar, you'd call fetch targeted to these URLs.
>> Scott Moss: Yep, yeah, you can call fetch in your code right now and hit this URL. Your frontend has no idea that there's an API that's also on the same domain and host as it is.

[00:09:44]
So it might as well be an external thing. I mean, obviously, you won't get the cores error cuz you're on the same domain. But as far as your client is concerned, it might as well be some external API. Let's try some more, so let's try a post. So how do you get data from the body?

[00:09:59]
Posting is a very common thing. Obviously, we can make this async, so we'll make that async, and we have a NextRequest. So if we wanna get things from the body, there's a few things you can do. So you can say req, or I'm sorry, await req. And then what you want, req.body, no, actually, is it like this now?

[00:10:29]
Actually, let me see. Thought it was something else, but let's log this and see what this is. And I'll return the NextResponse.
>> Scott Moss: NextResponse.json, I guess we could just echo this, let's just echo this.
>> Scott Moss: Body, okay, so now we have a post request, it's gonna just send back whatever you post up, if that's actually how you do it.

[00:10:58]
So let's make a new one here. I'll say post to user. How do you add? Here we go, body. They don't have a JSON, that sucks. [LAUGH] Okay, it's a format of the text, I was gonna say. I'm not using this anymore [LAUGH]. Things, let's post some things.

[00:11:31]
>> Scott Moss: Cool, so let's try that, send that up. Right, yeah, exactly, I didn't think that's actually what the rec body was. So to get the data, I'm pretty sure you have to await the request. Where is it?
>> Scott Moss: JSON, yeah, that's what it was, yeah. So you have to await the request.json, and then you can get the data.

[00:12:04]
>> Scott Moss: And then there we go, we get the things.
>> Scott Moss: Pretty simple. If you wanted to get the params, it's very similar to how you get the params in the pages. We don't have any params on this route, but you can access those. And then from there, the same rules apply for any route handle that you would make.

[00:12:31]
If you don't respond, this will hang, right, if I don't send a response. On this case, it actually just said, no, I'm just gonna die [LAUGH]. It's gonna do a 500. So you always wanna respond back with your handlers, otherwise, it's not useful. Next.js does have some really cool things now where you can respond immediately, but still continue processing stuff, which is really cool.

[00:12:56]
They have a, I forgot what it's called, it's wait until or something like that, that's really cool. It's really great for handling webhook requests. But mostly, this is pretty simple. You get access to the cookies. The way you get access to the cookies is the same way we have access to the cookies in the server actions, is through next headers, or is it?

[00:13:19]
Let's go see, I forgot what it was actually.
>> Scott Moss: It is next/headers. I don't know why they're autocomplete for me, doesn't like me. So you can get the headers here, you get the cookies here. And when you use them, you get access to all that, so the headers.

[00:13:43]
>> Scott Moss: Headers, together do that, .get, have them weighted. And then you can get the value of the header. So if you wanna get the authorization header, you can get the authorization header.
>> Scott Moss: And again, this is web standard syntax right here. This is not something Next.js made up, or anything like that.

[00:14:02]
If you go on any platform, whether it's edge or serverless, this is it. If you go look up the docs on the request object and response object, this is exactly what the standards are for the web. So that's why I like it, cuz you don't really have to learn anything new.

[00:14:20]
Now some people might ask, well, how do I do the stuff that I used to do in express, and make all the routes and stuff and things like that? Well, again, you use the file system for the routes. And if you wanna do things like middleware and stuff like that, we're gonna talk about global middleware.

[00:14:39]
But if you wanna do local middleware, I only wanna add middleware to this, because again, this is just a function. It's literally just a function. You can make your own abstraction for middleware, you can do a higher order function, right? So if I wanted to do something that says, always check the user, and I wanna do it on a route level, not a global level, I can do something like, const withUser, right?

[00:15:02]
And this is gonna take in a handler. Or even better, it'll be something like this. This might be async, right? So I can do something like that, and I could have this, take it there. There's so many ways you can do it, right, but there really isn't anything that you can't do.

[00:15:21]
So in this case, you might say, this takes a handler, and then it does this.
>> Scott Moss: Async, checks user,
>> Scott Moss: Get the results. Or actually in this case, it would just be like, if user, go ahead and return the handler.
>> Scott Moss: Something like that, you get the request objects and stuff here.

[00:15:53]
So you can make your own abstractions however you wanna do it. It's just a function. So however you wanna do it, you can do it that way, pretty simple. So why would you make these if you don't need to? If we can use server actions for everything. Yeah, for the app that you're making, maybe you don't need API routes.

[00:16:09]
But at least as far as how the app is consuming data and creating data, maybe you don't need API routes for those use cases. There are some use cases where you would need to go across the wire manually for a route from your app. And then now you have that.

[00:16:24]
The other use cases are, what if your app has to handle webhooks? That's a very common thing. I can't remember an app that I've built today that didn't have to handle a webhook of some sort. You would need to make a route for that, so you would make these API routes.

[00:16:37]
What if you needed to make a developer API? Maybe that's part of your product offering, is that you let developers build on top of your product by offering a developer API. This would be your developer API, you would do it here, if you so choose. So there are other use cases outside of being the mechanism in which your actual UI fetches and creates data, especially if you're getting into workflows, and AI, streaming, and all this stuff.

[00:17:06]
The use cases can go beyond just basic CRUD. So there are still use cases. It's just, for the CRUD stuff that you do in your app, you almost never need this, in my opinion.
>> Speaker 3: Quick question. So it would be, in your opinion, a recommendation to have the server actions, and then separately just expose the APIs as needed.

[00:17:31]
Or is there a way to just code once and then generate automatically the other so that you have more consistency?
>> Scott Moss: Yeah, so that's a great question. So the question was, can I just write the code once and have some consistency between the server actions and the API routes?

[00:17:46]
Yeah, a very good abstraction that I do, actually, is in my actions. For instance, let's look at this action here. You couldn't import these into your route handlers without some type of issues. But let's say, I have a route that creates an issue, but I also have a server action that creates an issue.

[00:18:06]
Well, typically what I would do is, I know that because both of these run in a request environment. All this code is gonna work in the API route, it's also gonna work on the Next.js server action. So what I'll do is I'll build a function that just takes this logic, and I'll use that function in here, and I'll use that same function in the route.

[00:18:30]
So it's just one function that I'm using in two different places. And the server actions just become shells of just being like, you're just wrapping some logic, so I can expose it as a server action. But the logic itself is independent of a server action, is independent of API route, it's independent of a data access layer function.

[00:18:47]
It's just like, this is code that runs on a server and runs during a request. And that's a very common thing that I see.
>> Scott Moss: Cool, any other questions?
>> Speaker 4: So the parameters for the dynamic segments, they come through the params on the Get function and Post function?

[00:19:12]
Or is it kinda with the next headers and cookies, is it something with?
>> Scott Moss: Yeah, it comes through like this.
>> Speaker 4: Okay.
>> Scott Moss: Yep, so pretty much the same thing.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Start a 7-Day Free Trial