-
Notifications
You must be signed in to change notification settings - Fork 26.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom server logic / routing #25
Comments
Can't get this this to working, I have tried to create a
but still showing 404 with no logs printed on console |
This should be fairly easy to implement. Wanted to hear comments about whether the proposed API makes sense to you all. |
Might be easier to have a convention on say |
Without realizing this issue existed I have done some work toward this already. It allows for custom endpoints placed in an Outline of changes:
An example endpoint export default function ({ req, res, params }, { dir, dev }) {
return { message: 'Hello world!' }
} And response from {"success":true,"body":{"message":"Hello world!"}} |
@jmfirth That looks great and is exactly what I am looking for. I can also see it being very useful as I have a really small app with only a few api calls. It would be awesome not to have to create a separate server project for my app. What are the |
A more general answer is that it follows the same general convention that the |
this should be merged into master |
After reading the home page of the project and this issue some things are not clear to me. Please, consider that i only have a very superficial understanding of the project but maybe my doubts can help you clarify some things about the project itself even in the home page.
|
Would you allow for |
I think it'd be really smart to expose a micro type contract: you can resolve the promise to an object and it gets rendered as JSON automatically :) |
Also, if you want to parse incoming JSON, you can just use micro tools! import { json } from micro
export default async function ({ req, res }) {
if (path === '/woot') {
const body = await json(req)
}
} I like this a lot as it preserves minimalism and great performance while allowing for unlimited power! |
|
Will be nice to have method for serving static files. import { sendFile } from 'next/server'
export default async function ({ path, req, res }) {
if (path === '/foo/bar.png') {
await sendFile(res, './build/bar.png')
}
} |
@dotcypress you can make a folder called |
@rauchg I spent some time this morning refactoring the example I posted above and am centering on a similar approach with differences:
const entries = await glob('!(node_modules|static)/**/*.js', { cwd: dir }) And modified all the JS loader constraints to simply:
addRoute (path, fn, method = 'GET') {
this.router.add(method.toUpperCase(), path, fn)
}
export default function (addRoute) {
addRoute('/api/:path+', async (req, res, params) => {
// do something and manipulate `res`
}, 'GET')
} This approach still has a way to go but I like how it's all coming together in my test app. |
A concrete example of changes: jmfirth@d63bf53 And example plugin that enables the same sort of |
I wonder if we can extract some parts of import next from 'next-core'
import http from 'http'
const render = next({ /* settings */ })
http.createServer((req, res) => {
if (req.url === '/a') {
render(req, '/b')
.then((html) => {
res.setHeader('Content-Type', 'text/html')
res.end(html)
})
}
}) |
@nkzawa I was thinking that taking complete control of the process would be really cool! Specifically, so that you can attach other things to the http server, handle I still think that |
Alternatively, this is one of the examples where "ejection" could be really cool to implement. Let's say you don't want |
What if you can write a server using any modules, but can't use // ./some/path/my-server.js
const { renderComponent, serveStatic } = require('next/server')
const http = require('http')
http.createServer((req, res) => {
// ...
}).listen(3000, () => {
console.log('Ready!')
}) and run:
|
I love that idea provided that |
Using a |
One use case: using next on top of FeathersJS... Been doing some basic ssr with FeatherJS and the output of CRA build but, using next would be great (as a hook for express app.get('*', nextjs(req, res, next)); |
@mbilokonsky I agree that a lot of this can be handled at the proxy level. But we also have to be realistic in that people will need at least some access to the underlying server. This API tries to expose the most minimal surface for doing that, without introducing or advocating bad practices (like tucking your entire server API into one process). I'm thinking about writing a document about "best practices" in terms of separation of APIs in the backend for Next to avoid that situation |
This would be perfect for sites powered by a CMS api. The handler could query the CMS using the route data and render different page (templates) accordingly. |
For custom routes, why abandon the core To that end, I suggest using express/rails style route conventions in the file names. So in my example, I would literally name my file |
Solving my own problem (#25 (comment)) with #223 |
I like making the "file system as an api" more powerful, but I also consider that the "default resolver", allowing more powerful url handling when needed. Of course this project should not be everything for everyone. But this extension point would open up a lot of cool possibilities. A CMS backed React site being just one of which. Speaking of which, it would be nice if |
I would stick to just routing and think that rails does it well:
This would look something like this: const {route} = require('next/server')
module.exports = [
route('/about', {to: 'about'}),
route('/user/:username', {to: 'user'})
];
I think in the solution described in the issue description you would still need a way of passing information to the page / component rendered (as @eirikurn also mentioned) and the imperative nature would make it hard to predict routes. My assumption is that with unpredictable routes the code splitting could become hard or sub optimal. How would |
Bump: Curious if there is any movement on this PR? |
Yes. I'm going to write a ticket specifying the final API we will implement On Sun, Nov 20, 2016 at 9:15 PM Ari [email protected] wrote:
|
Closing this in favor of "Programmatic API": #291. Keep track of that issue to learn about the progress of its implementation. Closing this as it's no longer an exploration. |
Like @rauchg mentioned, having a similar function to the "eject" of create-react-app would be great. It would comfort users that doubt to use Next.js because of the "closed environment". |
Is @jmfirth's suggestion implemented, or is a custom Express server the way to implement an API (custom backend)? |
Custom server is the way to go 👍 |
or in
package.json
:Let's say you want to override the default mapping between filesystem and route, you could set up something like this:
The function would receive a context object with the following properties (as far as I have thought about it):
path
the intended path of the request. This is so that if we request/a.json
or/a
, the path is still/a
, which simplifies the logic for the programmerreq
the original request from noderes
the original response from nodeThe return value can be a
Promise
. Ifundefined
is returned, it performs the default behavior.This file provides an opportunity to short-circuit (like send a
301
), add global security / authentication requirements, etc.[1] We might or might not want to transpile this file. Since it's "server-only", I think it's ok to assume it just supports whatever the version of Node.js you're running.
The text was updated successfully, but these errors were encountered: