We can create server-side rendered React apps and static sites easily Next.js.
In this article, we’ll take a look at dynamic API routing and middleware with Next.js.
Dynamic API Routes
We can create dynamic API routes by following the usual file naming convention.
In the pages/api folder, we can create a file with a name that’s surrounded with brackets.
For example, we can create a pages/api/post/[pid].js and write:
export default (req, res) => {
  const {
    query: { pid },
  } = req
  res.end(`Post: ${pid}`)
}
Then we can make a request by going to http://localhost:3000/api/post/foo.
And we’ll get Post: foo displayed as a result.
We can set up our routes with common REST patterns.
For example, we can use GET api/posts/ to get a list of posts.
And GET api/posts/1 gets a single post.
Catch-All API Routes
We can create a catch all API route by using ... in the file name.
For example, we can create the pages/api/post/[...slugs].js file and write:
export default (req, res) => {
  const {
    query: { slugs },
  } = req
  res.end(`Post: ${slugs.join(', ')}`)
}
Then when we go to http://localhost:3000/api/post/foo/bar, we get:
Post: foo, bar
returned.
Optional Catch-all API Routes
Also, we can create catch-all API routes that don’t always expect URL parameters to be passed in.
To do that, we wrap our file name with 2 square brackets around its name.
So we can create a file called pages/api/post/[[...slugs]].js and add:
export default (req, res) => {
  const {
    query: { slugs },
  } = req
  res.end(`Post: ${Array.isArray(slugs) && slugs.join(', ')}`)
}
We have a file with its name wrapped with a square brackets.
In the code, we check if slugs is an array and then return the array entries joined together.
API Middlewares
API roiutes provide built in middleware to parse incoming requests.
They include:
- req.cookiesto parse cookies
- req.queryto parse query strings
- req.bodyto parse request bodies.
Custom Config
Every API route can export a config object to change default configs.
For example, we can write:
export default (req, res) => {
  res.end(`Post: ${req.body}`)
}
export const config = {
  api: {
    bodyParser: {
      sizeLimit: '1mb',
    },
  },
}
to create an API route with a size limit imposed on the request body.
Also, we can disable body parsing with:
export default (req, res) => {
  res.end(`Post: ${req.body}`)
}
export const config = {
  api: {
    bodyParser: false,
  },
}
We set bodyParser to false to disable the body parser.
The externalResolver property is a flag that tells the server that the route is being handled by an external resolver.
It’ll disable warnings for unresolved requests.
We can use it by writing:
export default (req, res) => {
  res.end(`Post: ${req.body}`)
}
export const config = {
  api: {
    externalResolver: true,
  },
}
Conclusion
We can add dynamic routes and route middleware with Next.js.
