Dynamic API Routes
What are Dynamic API Routes
Just like dynamic routes in pages, you can also create dynamic API routes.
The API route pages/api/post/[pid].js
will have the following code:
export default function handler(req, res) {
const { pid } = req.queryres.end(`Post: ${pid}`)
}
A request to /api/post/abc
will respond with the text Post: abc
.
Index Routes and Dynamic API Routes
Common pattern for setting up routes
GET api/posts
Gets a list of posts and is probably paginated.
GET api/posts/12345
.Gets post id 12345
Two Ways to model this
Option One
/api/posts.js
/api/posts/[postId].js
Option Two
/api/posts/index.js
/api/posts/[postId].js
Both options are allowed. You can not only use /api/posts/[postId].js
because Dynamic Routes do not have an undefined
state so GET api/posts
will not match the above under any circumstance.
Catch all API Routes
Just as with 'regular' dynamic routes, you can also extend API Routes in to catching all the paths by adding three dots in the brackets.
pages/api/post/[...slug].js
Will match
/api/post/a
.But will also match
/api/post/a/b
.
When you use a matched parameter, it will be sent as a query parameter to the page and will turn it in to an array. The path /api/post/a
will have the following query: { "slug": ["a"] }
.
An API route could look like this if it was made for pages/api/post/[...slug].js
:
export default function handler(req, res) {
const { slug } = req.query
res.end(`Post: ${slug.join(', ')}`)
}
If you request /api/post/a/b/c
, it will respond with the following text: Post: a, b, c
.
Optional Catch All API Routes
Again, the same as with 'regular' dynamic routes.
All routes can be made optional if you include the parameter in double brackets like [[...slug]]
.
pages/api/post/[[...slug]].js
will match
/api/post
will match
/api/post/
will match
/api/post/a/b
etc.
The biggest difference is that because it is optional. the route without the parameter is also matched.
Caveats
Predefined API routes take precedence over dynamic API routes.
Dynamic API routes take precendence over catch all API routes.
This will lead to the following:
pages/api/post/create.js
will match/api/post/create
pages/api/post/[pid].js
will match/api/post/1
,api/post/abc
, etc.but not
/api/post/create.
pages/api/post/[...slug].js
will match/api/post/1/2
and/api/post/a/b/c
but not
/api/post/create
and/api/post/abc
.