[RFC] API routes
See original GitHub issueFeature request
Is your feature request related to a problem? Please describe.
Currently a lot of users create a custom server.js to handle creating their API.
However this causes some issues:
- React rendering is sync, meaning that while rendering performance for requests to the API can differ
- The API and routing solely depend on the custom server, meaning that it can only be deployed as one server
- Because it’s one server the bundle size of this server is quite heavy (slow bootup)
- Because it’s one server your complete API goes down if one handler has a uncaught exception
There’s also some other ergonomic issues:
- Because the server runs outside of Next.js it is not compiled, meaning you can’t use
import/export - Because
import/exportis not supported we’ve seen many users start compiling their customserver.jswhich introduces another build step, that is different from Next.js. Furthermore they addnodemon, to sort of get hot reloading of the server file, which means Next.js is rebooted every time you make changes to the API, losing all compilation state. - We’ve seen this extra build step being implemented wrong many times, for example in doing so tree-shaking was disabled because of Babel options being different for client/server compilation.
The solution to most of these problems revolve around 3 issues:
- Dynamic routing
- Being able to create APIs
- Middleware (see #7208)
Describe the solution you’d like
This proposal goes into the API creation part of the issue.
The solution that I have in mind involves a few small changes to Next.js. It comes down to:
- The user will be able to create a
apidirectory inside ofpages. This is becausepages/apihas to do with routing and we might changepagestoroutesin the future. - This
apidirectory is automatically mapped to/api(as expected) - So for example you can create
api/posts.jsand it will be mapped to/api/posts - The handle will look like:
export default (req, res) =>this means that you can use any of the http server frameworks likeexpressmicroetc. - In case of
microI think we should change the API of the programmatic usage to this:
import micro from 'micro'
export default micro((req, res) ⇒ {
return 'Hello World'
})
Current invoking micro() will return a Node.js http.Server which doesn’t work well with just req, res as a handler. This also ties into using micro standalone with @now/node . Doing this will allow us to deprecate micro-dev too in favor of using Next.js / now dev + @now/node
Usage for express would look like:
import express from 'express'
const app = express()
export default app
Note that express would not be in charge of routing, just the request handling, meaning that in most cases you actually want to use micro as it’s much smaller and has better performance.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:130
- Comments:34 (22 by maintainers)

Top Related StackOverflow Question
Is there any reason the api directory needs to be inside pages? It feels like it would make more sense to me to have it be outside 😀
Echoing @Janpot here -
fetch('/API/foo')from within Components/getInitialProps should allow accessing API routes directly.