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.
Download my free Next.js Handbook
More next tutorials:
- Getting started with Next.js
- Next.js vs Gatsby vs create-react-app
- How to install Next.js
- Linking two pages in Next.js using Link
- Dynamic content in Next.js with the router
- Feed data to a Next.js component using getInitialProps
- Styling Next.js components using CSS
- Prefetching content in Next.js
- Using the router to detect the active link in Next.js
- View source to confirm SSR is working in Next.js
- Next.js: populate the head tag with custom tags
- Deploying a Next.js application on Now
- Next.js: run code only on the server side or client side in Next.js
- Deploying a Next.js app in production
- How to analyze the Next.js app bundles
- Lazy loading modules in Next.js
- Adding a wrapper component to your Next.js app
- The icons added by Next.js to your app
- The Next.js App Bundles
- How to use the Next.js Router
- How to use Next.js API Routes
- How to get cookies server-side in a Next.js app
- How to change a Next.js app port