How to use Next.js API Routes
Learn this powerful technique provided by Next.js to create an API endpoint within a Next.js app
In addition to creating page routes, which means pages are served to the browser as Web pages, Next.js can create API routes.
This is a very interesting feature because it means that Next.js can be used to create a frontend for data that is stored and retrieved by Next.js itself, transferring JSON via fetch requests.
API routes live under the /pages/api/
folder and are mapped to the /api
endpoint.
This feature is very useful when creating applications.
In those routes, we write Node.js code (rather than React code). It’s a paradigm shift, you move from the frontend to the backend, but very seamlessly.
Say you have a /pages/api/comments.js
file, whose goal is to return the comments of a blog post as JSON.
Say you have a list of comments stored in a comments.json
file:
[
{
"comment": "First"
},
{
"comment": "Nice post"
}
]
Here’s a sample code, which returns to the client the list of comments:
import comments from './comments.json'
export default (req, res) => {
res.status(200).json(feeds)
}
It will listen on the /api/commments
URL for GET requests, and you can try calling it using your browser:
API routes can also use dynamic routing like pages, use the []
syntax to create a dynamic API route, like /pages/api/comments/[id].js
which will retrieve the comments specific to a post id.
Inside the [id].js
you can retrieve the id
value by looking it up inside the req.query
object:
import comments from '../comments.json'
export default (req, res) => {
res.status(200).json({ post: req.query.id, comments })
}
Heres you can see the above code in action:
In dynamic pages, you’d need to import useRouter
from next/router
, then get the router object using const router = useRouter()
, and then we’d be able to get the id
value using router.query.id
.
In the server-side it’s all easier, as the query is attached to the request object.
If you do a POST request, all works in the same way - it all goes through that default export.
To separate POST from GET and other HTTP methods (PUT, DELETE), lookup the req.method
value:
export default (req, res) => {
switch (req.method) {
case 'GET':
//...
break
case 'POST':
//...
break
default:
res.status(405).end() //Method Not Allowed
break
}
}
In addition to req.query
and req.method
we already saw, we have access to cookies by referencing req.cookies
, the request body in req.body
.
Under the hoods, this is all powered by Micro, a library that powers asynchronous HTTP microservices, made by the same team that built Next.js.
You can make use of any Micro middleware in our API routes to add more functionality.
I wrote 17 books to help you become a better developer, download them all at $0 cost by joining my newsletter
JOIN MY CODING BOOTCAMP, an amazing cohort course that will be a huge step up in your coding career - covering React, Next.js - next edition February 2025