RFC: API Routes #34051
Replies: 34 comments
-
This is a great idea. I've been using next.js for well over a year and have needed server.js for custom routing nearly the entire time. When I started moving some projects over to Zeit Now, i realized my server.js convention didn't work and begun to use Big thing I like about this solution: it reduces lock-in to Now service slightly since there'd be a standardized way to do parameterized routing and APIs within next.js. Woo! (and as a marketing thing, it'd be easier for people to bring their projects to Now later on down the line since both apis and routing are standardized) |
Beta Was this translation helpful? Give feedback.
-
This is interesting. I would love to do away with server.js yet I always find myself needing it eventually. I'm hoping that now dev will alleviate some of the use cases but that's only for use with now hosting. At work we will continue to have to come up with our own solution. Some things I currently use server.js for:
|
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
Would it make sense then to add a |
Beta Was this translation helpful? Give feedback.
-
@timneutkens yes, all great points. I do think that in between URL rewriting (next proposal), this proposal and |
Beta Was this translation helpful? Give feedback.
-
Having an |
Beta Was this translation helpful? Give feedback.
-
Echoing @Janpot here - |
Beta Was this translation helpful? Give feedback.
-
I like how the api interface looks very similar to serverless functions. To make the most use out of those we could look into maybe exporting Express routers (or whatever equivalent micro routers are) which would give us the power of defining custom paths (with middlewares) extending upon the filename. Or, maybe a configuration file (similar to serverless.yml) for defining the routes (which may not be the preferred method given the how next uses pages for routes). |
Beta Was this translation helpful? Give feedback.
-
It is, because it'll be deployed as serverless functions.
As said in the proposal "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."
The file path is the configuration here. We'll soon introduce dynamic routing to cover most cases. |
Beta Was this translation helpful? Give feedback.
-
@developit |
Beta Was this translation helpful? Give feedback.
-
Im happy to see this direction, as it's been a very helpful pattern with https://github.com/ericclemmons/polydev Some suggestions, from my experience:
(Sorry, on mobile so poorly formatted) |
Beta Was this translation helpful? Give feedback.
-
@lucleray I was kind of thinking in the direction of having an interface that aligns more closely to // /api/test.ts
import serve, { Response } from 'next/serve';
export default serve(async ({ request }) => {
return new Response('hello world');
}); on the server, import fetch from 'next/fetch';
// ... in getInitialProps
const response = await fetch('/api/test'); During server render though, when called in edit 🤔 I guess in |
Beta Was this translation helpful? Give feedback.
-
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 😀 |
Beta Was this translation helpful? Give feedback.
-
@jescalan It seems like they're thinking of renaming "pages" to "routes". |
Beta Was this translation helpful? Give feedback.
-
I saw that, but this is a massive breaking change and probably will take a bit to roll out. I feel like just keeping |
Beta Was this translation helpful? Give feedback.
-
I agree with @jescalan @PullJosh to move An example website using Maybe Next could be to have both |
Beta Was this translation helpful? Give feedback.
-
I would like to chime in about one common "non-pages but also non-api" use case—oauth2 flow. You dont need client side pages for it, but its also not an api. https://github.com/iamstarkov/topics-manager/tree/master/pages/auth/github Right now with Next you are forced to use |
Beta Was this translation helpful? Give feedback.
-
What about support for middleware like passport ? |
Beta Was this translation helpful? Give feedback.
-
I've started playing with the API routes on the canary channel and already they have made the dev experience much nicer. One comment I would make: there may need to be a way to prevent api routes from being disposed when using the development server. I have several API routes that cache their requests to speed up subsequent fetches. However, without increasing |
Beta Was this translation helpful? Give feedback.
-
API routes have been released in Next.js 9! Read the blog post to learn more and give them a try! Thank you to everyone who provided feedback. |
Beta Was this translation helpful? Give feedback.
-
Is there ideas to make regular page to listen for api (POST/PUT/.. etc requests) GET /posts/p leads to rendering (using getInitialProps) |
Beta Was this translation helpful? Give feedback.
-
What is the reasoning behind it @slavb18? |
Beta Was this translation helpful? Give feedback.
-
Initially I was looking for basepath support for api #4998, becouse currently API route is unprefixed and cannot be used in multi-application-deployment case without redirecting proxy. But after that I realized that really I need page controllers.
this resolves to
So I need to GET and POST on page URL. Is there some example/workaround to make custom routing for POST? |
Beta Was this translation helpful? Give feedback.
-
May be there should be more generic conception instead of "api/pages" - Web Resource E.g. /resources/XXX could be used as handler for GET/POST/PUT/other request types Then GET /YYY routes to /resources/YYY.js (is exists GET handler), otherwise to /pages/YYY POST/PUT/etc /YYY routes to /resources/YYY.js where YYY.js could contain: per-http-methods, like get(),post(),put(),options(), etc |
Beta Was this translation helpful? Give feedback.
-
According to the docs https://nextjs.org/blog/next-9#api-routes we get And NextApiRequest does have a Other option is that since they extend the Ex: export default function handle(req, res) {
switch (req.method) {
case "GET":
break;
case "POST":
break;
default:
// https://nodejs.org/api/http.html#http_response_writehead_statuscode_statusmessage_headers
// Set status to 400 bad request
break;
}
} |
Beta Was this translation helpful? Give feedback.
-
Yes, I can handle any http method, but only on hardcoded path "/api" This is enough if there is only one application on host. But in cause of multi-application scenario this leads to path conflicts. (eg. corporate infrastructure with lots of interacting microservices: /app1, /app2, each with own api) Currently this can be fixed by proxy configuration (e.g. on Apache I can configure two separete ProxyPass /app1/api -> backend:port/api, /app1 -> backend:port/app1/ but this is workaround. Resource paths on backend should be symmetric to proxied app ) |
Beta Was this translation helpful? Give feedback.
-
This is more for people reading about the pages api features than a response to Tim. As of me testing it today, that works from variables set in next.config.js, and those variables are consumed in |
Beta Was this translation helpful? Give feedback.
-
In case of API routes you don't have to inline the variables at build-time, we're making it easier to use this pattern in development also: #11106 |
Beta Was this translation helpful? Give feedback.
-
I just stumbled across this discussion and wondering whether there's an idiomatic solution to this nowadays. How may I interact with a database through Also, how should errors be handled when abstracting database queries away into separate files? My initial idea is using a discriminated union as the return type, e.g.: import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
type QueryResult<T, E = unknown> =
{ success: true, data: T } |
{ success: false, error: E };
export async function findUserById(id: string): QueryResult<User> {
const user = await prisma.user.findOne({ where: { id } });
return user
? { success: true, data: user }
: { success: false, error: "An error has occurred." };
} |
Beta Was this translation helpful? Give feedback.
-
This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Beta Was this translation helpful? Give feedback.
-
Feature 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:
There's also some other ergonomic issues:
import
/export
import
/export
is not supported we've seen many users start compiling their customserver.js
which 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.The solution to most of these problems revolve around 3 issues:
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:
api
directory inside ofpages
. This is becausepages/api
has to do with routing and we might changepages
toroutes
in the future.api
directory is automatically mapped to/api
(as expected)api/posts.js
and it will be mapped to/api/posts
export default (req, res) =>
this means that you can use any of the http server frameworks likeexpress
micro
etc.micro
I think we should change the API of the programmatic usage to this:Current invoking
micro()
will return a Node.jshttp.Server
which doesn't work well with justreq, res
as a handler. This also ties into using micro standalone with@now/node
. Doing this will allow us to deprecatemicro-dev
too in favor of using Next.js /now dev
+@now/node
Usage for express would look like:
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.Beta Was this translation helpful? Give feedback.
All reactions