Check out a free preview of the full Introduction to Next.js course:
The "API Handlers" Lesson is part of the full, Introduction to Next.js course featured in this preview video. Here's what you'd learn in this lesson:

Scott demonstrates how to write an API handler that responds to all requests from a given URL, adds logic based on each API route, and uses the next-connect npm package as a middleware to simplify building the handler.

Get Unlimited Access Now

Transcript from the "API Handlers" Lesson

[00:00:00]
>> All right, now let's get into actually making some of these things do some stuff. So, yeah, here's a big tip. Next.js API routes are not the same as Vercel's Serverless API functions, although the setup is very similar. So they use Vercel, who are the creators of Next.js, and you want to use their Serverless functions, which are really good.

[00:00:24] The way that you make those Serverless functions look almost similar to what you're doing here. The biggest difference is, for the Serverless functions, by default the API folder is on the roots of your app. And you have to add a configuration file that tells Serverless functions how to map your functions to different events in the Serverless environment.

[00:00:44] So don't confuse these API routes with the API Serverless functions, because these API routes are not Serverless. These are not Serverless functions, these are absolutely not Serverless functions. If you want Serverless functions, you can do that with Vercel, but it has nothing to do with Next.js. You can add them to your Next.js app, but they're completely independent of Next.js, they just look the same.

[00:01:02] And I remember when I was first using this a long time ago, I got confused, so that's why I put that tip there. I was like, wait, are these Serverless or, how does this work? They're not, they're not the same, so don't confuse the two. This has nothing to do with Serverless, or Vercel.

[00:01:17] Whereas Serverless routes down here that you might make are completely dealing with Vercel and Serverless functions, and nothing to do with Next.js. I think they just thought that it was a good convention to make an API folder, since it works so well in Next.js, hey, why not use it for Serverless functions as well?

[00:01:32] And I don't blame them, it's a really good convention, so, really cool. All right, so, let's talk about handlers. So if you've never built an express app with Node, no worries, you can take this course here for Express and APIs with Node right here in Frontend Masters, that basically walks you through how to create APIs with Express in Node.

[00:01:53] If you haven't, not a big deal, it's actually really intuitive, at least for what we're gonna cover today. But, at the end of the day, that's kind of what Next.js does, it creates. It basically gives you the Connect, which is this framework that Express made popular, if you've ever used Express, and you have the middleware and all that stuff, there's actually something called Connect.

[00:02:13] Express just used to rely on it as a dependency, and then, I think, maybe 4.0, 3.0, somewhere in Express, they decided to get rid of it as a dependency, but they still kept the same syntax. But everything was from Connect back in the day, like eight years ago or something like that.

[00:02:28] And, most Node servers you see are kinda based off that, and Next.js is no different. So all you have to do in a file is, is do something like this. By doing this, we literally get an API. So for instance, I'm just gonna copy this. And, I'm going to add it to, almost deleted this user thing.

[00:02:46] I'm gonna add it to our API here. And that's it. I have an API now, 2/API. You notice there are no methods here, so if I'm doing a GET, PUT, PATCH, DELETE, I don't know what I'm doing, cuz I'm not, I'm not doing either those things, I'm gonna do all of those things.

[00:03:02] So we can test this out, so I'm just gonna restart very quick. Actually, let me get rid of this log for the theme, that's kind of making our output super noisy. I always like to log my theme sometimes, cuz if I'll do presets, and I don't know what the colors are or what they're called, so I'll log it out.

[00:03:19] So I can see the colors, and the sizes, and the fonts and everything, so I can use them. So, I usually keep that off for development. All right, so let's hit the API. I'm actually [SOUND]. I'm just gonna do a GET request, I'll just do a GET request here.

[00:03:33] And it's gonna be to our app, which, for me, is localhost 3000, if you didn't change your ports, the same thing. /API, I was gonna hit Enter, and then boom, I get back message, hello. It might look different than yours just because I have some json Chrome extension that makes this look like this.

[00:03:52] If you don't have the Chrome extension here, is gonna get back some black text on a white screen, but it's still json. So, yeah, pretty simple. We [LAUGH], we got a nice full API, I mean. Can someone, again, show me a framework that makes it easier to do this?

[00:04:08] This is the simplest API I've ever seen done ever. You didn't have to do anything, and it just worked. All you have to do is make a file, I didn't have to make a route, it just worked. And that, to me, is just really impressive, so. I really like what they're doing here with this.

[00:04:25] So, let's keep moving. And, so now, yeah, that's really cool and all, but I mean, who wants to do all this stuff for all the complicated server logic they're gonna have? We need a little more than this. It may sound a little closer to Express. And out of the box Next.js doesn't give you that experience, but I think that's a good thing, because it is just based off Connect, you can literally use whatever you want.

[00:04:50] And, there's a lot of packages out there to kinda make this easier. But I've landed on one, and we'll kinda talk about that. But basically, some of the things that we wanna be able to do is, we want to be able to respond to a URL like this, but be able to split off the methods, whether it's a GET, a PUT, A DELETE.

[00:05:06] Because right now, I can make any requests I want to this, with any method and is always gonna return the same. It doesn't matter, I can test this out right now. So, now I'm gonna use HTTPie, which is like cURL for humans, to test the non GET request, cuz the browser can only test a GET requests.

[00:05:24] So if I wanna test the post, I can say HTTP, which is the command line for HTTPie, that's so hard to say. Then I could say, PUT, and I'm just gonna say, 3000, this is a shortcut for localhost 3000, and then /API, which is where our API is.

[00:05:42] And then I can do that. And you can see, I still get back message hello, I could do the same thing with posts. I get back message, hello. I mean, I can go on and on. DELETE, doesn't matter. It's always gonna send it back, and that's because I'm not doing anything with the methods here.

[00:05:59] So, yeah, you could just split on the methods by using request.method = GET do this, request.method = DELETE do this. But that's really gross, and Express already solved this, so why can't we use that here? So let's do that. So here's a plugin that I like to use, or a module, it's called next-connect.

[00:06:18] It basically allows you to do it. So, you can turn any handler into an Express-like router that has its own methods on it, and also be able to use any Connect-based middleware. So for this case, I'm using cors, so, that works. And then you just export your handler.

[00:06:34] So I'm just gonna install next-connect here. Like that. And then what we can do is, we can import this up top. So import, I was gonna call it nc from next-connect. And then what I can do is, I can make a handler, like this, which is nc, and then it's just chainable.

[00:07:00] So now I can say, I wanna be able to get, and then I can say req, res. So, if you've never used Express, req and res are short for request and response. So here's the incoming request, and here's how you respond to it. So, that's what that means.

[00:07:18] I can also do something like, post((req, res,)). And the other thing to note about this is that, you can do async functions in here, so. But this stuff needs to be async as you're doing some database stuff. No problem, they can be async. You can do all this stuff in here, they can do promises, it's all good.

[00:07:37] So we have this GET request here, so now I'll just say like, req.json, and I'll send back a message that says, ok, and I'll do the same thing for post, that just says posted it, like that. So then I'll. I think I don't have to restart it, I think that was good to go.

[00:07:58] So now let's test. See what happens when I try to do a DELETE. Not found. Can't do DELETE anymore, cuz we didn't create a method for that inside of that nc handler, so now it's a 404. But if I go back and I try to do a, what did I do, post?

[00:08:15] Yeah. Post here. Res.json. I put req, sorry, res.json and, res.json. I do a post here, boom, I get the posted message, and then obviously if I go back to the browser and I do that, I get the GET message for ok. All right, so, that to me is, I mean, extremely powerful.

[00:08:41] It kinda reminds me of a Serverless function, if you've ever used Serverless functions before, it kinda feels that way. Except for it's not a Serverless function, it's just not a Serverless functions, it's on Express. So, this was pretty legit, I mean, you could really get the app moving really quick, really fast with this.

[00:08:56] And again, this code is not living. It's right next to your pages, which are client-side react components, but this code never gets shipped to the browser, this is never gonna be in the browser, this is only server-side, it's a completely different bundle. So even though it lives there, it's separate.

[00:09:11] And to me, logically working on it as a developer, it just makes more sense than what I currently have set up in different places of our organization. Whereas it's like, you got this API over here, it's in this repo, and this thing, and maybe you're using Docker, it's a lot.

[00:09:27] This kind of just simplifies it a lot, in my opinion. So, monorepos were always legit. Microservices just changed it all, but you can still have a monorepo with microservices, you just have. What is it? Like Yarn, Yarn Workspaces, or using Learner, or something like that, so you coul still do that.

[00:09:48] Especially they're all Node. So, this having the code next to each other just works better, in my opinion.