You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm currently using the library without any HTTP server, just as a router and middleware engine. So req.send() doesn't exist for me (and shouldn't), I simply call next() until there is no more middleware in the stack.
Your first example is almost there: getting to that last callback function with no error is when there is no route, so you should just change your test to !err.
As far as the second example, that is not possible, as any middleware can rewrite the url like req.url = and the routing will continue based on the new URL (or method), similar to the Apache mod_rewrite. This means in order to determine if a given request will match a route, the middlewares need to process on the request in order to apply any possible rewrite rules.
The problem with the above is that the 'finish' callback is executed always, whether the route exists or not. But by the sound of it (due to possible rewrites of the url) there is no clear way of determining if an exact route exists during runtime?
On a slightly different note...
Is there any way of getting the response object in the 'finish' callback? Reason being that I want to somehow promisify the execution of a route. Something like:
// Promisify a route execution.
function executeRoute (route, url, req = {data: {}}, res = {}) {
return new Promise((resolve, reject) => {
route.use((req, res) => {
resolve({ok: true, ...res})
})
route({...req, method: 'GET', url}, res, err => {
if (err)
reject(err)
})
})
}
module.exports = {executeRoute}
But the problem with that is that it adds a new route each time it's called. It works perfectly; but only once... because I don't call next(). Basically I want to be able to fire a method which sets off a chain of middleware and eventually returns a result. As I don't have req.send, I'm unable to capture my result.
Ideally I want the ability to add some middleware that is only added for that single execution of the route. Such that I can capture results but not effect the make-up of the stack.
Is considered a route that does not exist in this module, as it calls next(), indicating that the route doesn't apply to that given request. This is because route matching is fully programmatic: you can match on anything you want, and next() is there to say "hey, this request doesn't match here, so keep going".
Is there any way of getting the response object in the 'finish' callback?
It is not provided, as the response object is not something produced by the router function, it is just an input. The reference would already be available in your scope when you call router.
As far as your later part of the quest, I think I lost you there, and I'm not sure what exactly you are attempting to do, not sure what an answer is.
Which allows me to modularise my middleware and separate concerns. But it sounds like, within this setup, I should not call next() in someOtherMiddleware if I consider it the completion (and therefore an existing) route? That kinda makes sense actually.
The latter part of the question is really to do with how my application consumes and 'runs' the route. Because I'm not using a server, I've just been handing empty objects as the response. But I suppose in order to get a response from the executed route, I should send a response object akin to {send: callback} and call res.send('whatever') in my middleware when I consider the route execution fulfilled?
Middlewares are not the same as the route handlers. A middleware is typically expected to call next(), but not a route handler, which is expected to either respond to the request (populate the response object) or call next() to try and see if there is another route handler that will fulfill it.
I guess, what are you trying to do with the module? I thought perhaps you were just trying to write some unit tests around it, but still would be using it to write something that would actually work under the HTTP server, is that not the case?
Perhaps my use case is a strange one. Essentially I wanted to use router without a server such that I could run it in various browser and node distros. We have a core product which needs to have several interfaces. One is a server and more akin to a traditional express application, the other is a devtools extension, an electron interface etc. And there may be others. So I'm using it as a sort of headless router, which will contain all of our business logic.
Basically we wanted to leverage the modulability of routes and middleware, and have our main business logic operate outside of a particular interface. Obviously it's more complex than the above but it should go some way at explaining the use case.
Activity
dougwilson commentedon Jul 28, 2020
Hi @shennan ,
Your first example is almost there: getting to that last callback function with no error is when there is no route, so you should just change your test to
!err.As far as the second example, that is not possible, as any middleware can rewrite the url like
req.url =and the routing will continue based on the new URL (or method), similar to the Apache mod_rewrite. This means in order to determine if a given request will match a route, the middlewares need to process on the request in order to apply any possible rewrite rules.shennan commentedon Jul 28, 2020
Thanks for the response @dougwilson.
The problem with the above is that the 'finish' callback is executed always, whether the route exists or not. But by the sound of it (due to possible rewrites of the url) there is no clear way of determining if an exact route exists during runtime?
On a slightly different note...
Is there any way of getting the response object in the 'finish' callback? Reason being that I want to somehow promisify the execution of a route. Something like:
I wrote something like this:
But the problem with that is that it adds a new route each time it's called. It works perfectly; but only once... because I don't call
next(). Basically I want to be able to fire a method which sets off a chain of middleware and eventually returns a result. As I don't havereq.send, I'm unable to capture my result.Ideally I want the ability to add some middleware that is only added for that single execution of the route. Such that I can capture results but not effect the make-up of the stack.
Am I trying to square-peg a round hole?
dougwilson commentedon Jul 28, 2020
Hi @shennan the callback should not be called if you have a route there. Can you share your route code? For example,
Is considered a route that does not exist in this module, as it calls
next(), indicating that the route doesn't apply to that given request. This is because route matching is fully programmatic: you can match on anything you want, andnext()is there to say "hey, this request doesn't match here, so keep going".It is not provided, as the response object is not something produced by the
routerfunction, it is just an input. The reference would already be available in your scope when you call router.As far as your later part of the quest, I think I lost you there, and I'm not sure what exactly you are attempting to do, not sure what an answer is.
shennan commentedon Jul 28, 2020
Ok, so the library assumes that a route is only fulfilled when
next()is not called? I have something like...Which allows me to modularise my middleware and separate concerns. But it sounds like, within this setup, I should not call
next()insomeOtherMiddlewareif I consider it the completion (and therefore an existing) route? That kinda makes sense actually.The latter part of the question is really to do with how my application consumes and 'runs' the route. Because I'm not using a server, I've just been handing empty objects as the response. But I suppose in order to get a response from the executed route, I should send a response object akin to
{send: callback}and callres.send('whatever')in my middleware when I consider the route execution fulfilled?Thanks again for the continued advice. 👍
dougwilson commentedon Jul 28, 2020
Middlewares are not the same as the route handlers. A middleware is typically expected to call
next(), but not a route handler, which is expected to either respond to the request (populate the response object) or call next() to try and see if there is another route handler that will fulfill it.I guess, what are you trying to do with the module? I thought perhaps you were just trying to write some unit tests around it, but still would be using it to write something that would actually work under the HTTP server, is that not the case?
shennan commentedon Jul 28, 2020
Thanks @dougwilson
Perhaps my use case is a strange one. Essentially I wanted to use router without a server such that I could run it in various browser and node distros. We have a core product which needs to have several interfaces. One is a server and more akin to a traditional express application, the other is a devtools extension, an electron interface etc. And there may be others. So I'm using it as a sort of headless router, which will contain all of our business logic.
Best way to describe it is:
Basically we wanted to leverage the modulability of routes and middleware, and have our main business logic operate outside of a particular interface. Obviously it's more complex than the above but it should go some way at explaining the use case.