I want to check for a consistent URL parameter in each request in my Express.JS app. The base of the URL is always the same:
/command/UUID
But some times it can be
/command/UUID/something/1
The following code works only in the first case. As soon as I add another slash at the end, this middleware won't be executed.
app.all('/*/:uuid', function(req, res, next) {
console.log(req.params)
next();
});
I would appreciate if someone could help me out solve this issue.
Best.
Something like this:
app.all('/:command/:uuid/(*?)', function(req, res, next) {
console.log(req.params.command, req.params.uuid);
next();
});
What actually worked is the following code
app.set('strict routing', false );
app.all('/:cmd/:uuid*', function(req, res, next) {
console.log(req.params)
next();
});
And the result is as follow with this URL: /ip/165420/3123123/adasdsad
{ '0': '/3123123/adasdsad', cmd: 'ip', uuid: '165420' }
Related
Does anyone know if it's possible to get the path used to trigger the route?
For example, let's say I have this:
app.get('/user/:id', function(req, res) {});
With the following simple middleware being used
function(req, res, next) {
req.?
});
I'd want to be able to get /user/:id within the middleware, this is not req.url.
What you want is req.route.path.
For example:
app.get('/user/:id?', function(req, res){
console.log(req.route);
});
// outputs something like
{ path: '/user/:id?',
method: 'get',
callbacks: [ [Function] ],
keys: [ { name: 'id', optional: true } ],
regexp: /^\/user(?:\/([^\/]+?))?\/?$/i,
params: [ id: '12' ] }
http://expressjs.com/api.html#req.route
EDIT:
As explained in the comments, getting req.route in a middleware is difficult/hacky. The router middleware is the one that populates the req.route object, and it probably is in a lower level than the middleware you're developing.
This way, getting req.route is only possible if you hook into the router middleware to parse the req for you before it's executed by Express itself.
FWIW, two other options:
// this will only be called *after* the request has been handled
app.use(function(req, res, next) {
res.on('finish', function() {
console.log('R', req.route);
});
next();
});
// use the middleware on specific requests only
var middleware = function(req, res, next) {
console.log('R', req.route);
next();
};
app.get('/user/:id?', middleware, function(req, res) { ... });
I know this is a little late, but for later Express/Node setups req.originalUrl works just fine!
Hope this helps
This nasty trick using prototype override will help
"use strict"
var Route = require("express").Route;
module.exports = function () {
let defaultImplementation = Route.prototype.dispatch;
Route.prototype.dispatch = function handle(req, res, next) {
someMethod(req, res); //req.route is available here
defaultImplementation.call(this, req, res, next);
};
};
req.route.path will work to get the path for the given route. But if you want the complete path including the path of the parent route, use something like
let full_path = req.baseUrl+req.route.path;
Hope it helps
You can take a look at Router().stack, which has all the routes defined. In your middleware you need to manually compare the available routes with the one called to define actions.
Real simple question guys: I see a lot of books/code snippets use the following syntax in the router:
app.use('/todos/:id', function (req, res, next) {
console.log('Request Type:', req.method);
next();
});
I'm not sure how to interpret the route here... will it route '/todos/anything'? and then grab the 'anything' and treat is at variable ID? how do I use that variable? I'm sure this is a quick answer, I just haven't seen this syntax before.
This is an express middleware.
In this case, yes, it will route /todos/anything, and then req.params.id will be set to 'anything'
On your code, that is for express framework middleware, if you want to get any id in the server code using that route, you will get that id by req.params.id.
app.use('/todos/:id', function (req, res, next) {
console.log('Request Id:', req.params.id);
next();
});
Route path: /student/:studentID/books/:bookId
Request URL: http://localhost:xxxx/student/34/books/2424
req.params: { "studentID": "34", "bookId": "2424" }
app.get('/student/:studentID/books/:bookId', function (req, res) {
res.send(req.params);
});
Similarly for your code:
Route path: /todos/:id
Request URL: http://localhost:xxxx/todos/36
req.params: { "id": "36" }
app.use('/todos/:id', function (req, res, next) {
console.log('Request Id:', req.params.id);
next();
});
Yes, in your example youl get req.params.id set to 'anything'
A bit late to the party but the question mark in your question made me think of something that hasn't been touched upon.
If your route had a question mark after the id like so: '/todos/:id?', id would be an optional parameter, meaning you could do a getAll() if id was omitted (and therefore undefined).
This is called Path params and it's used to identify a specific resource.
and as all answer how to get the value of the path params
app.use('/todos/:id', function (req, res) {
console.log('Request Id:', req.params.id); // 'anything'
});
read more about params type
https://swagger.io/docs/specification/describing-parameters/
I'm trying to log every request made to my sails application, but I can't find a way to log the response associated with a request.
I added this custom middleware in the config/http.js file :
myRequestLogger: function (req, res, next) {
req.on("end", function(){
sails.log(res.statusCode);
});
return next();
}
But it doesn't work properly, I can get the 200 codes, buta res.forbidden or res.notFound response is not logged. Any idea about how I could handle that ?
Thank you
You can override that in api/responses itself. Here is simplified override:
// api/responses/forbidden.js
module.exports = function(err, viewOrRedirect) {
// ... Sails logic
this.req._sails.log.verbose();
}
But, if you expect that your middleware above can do this, you're wrong. Your middleware should looks similar to this:
myRequestLogger: function(req, res, next) {
req._sails.log.verbose('YOUR LOG');
return next();
}
Ok, I have found the answer by reading this stackoverflow post : https://stackoverflow.com/a/11841877/2700309
Apparently there is a 'finish' event emitted just before the response is send to the client. So the right code would be :
myRequestLogger: function (req, res, next) {
res.on("finish", function(){
sails.log(res.statusCode);
});
return next();
}
And this seems to work!
Does anyone know if it's possible to get the path used to trigger the route?
For example, let's say I have this:
app.get('/user/:id', function(req, res) {});
With the following simple middleware being used
function(req, res, next) {
req.?
});
I'd want to be able to get /user/:id within the middleware, this is not req.url.
What you want is req.route.path.
For example:
app.get('/user/:id?', function(req, res){
console.log(req.route);
});
// outputs something like
{ path: '/user/:id?',
method: 'get',
callbacks: [ [Function] ],
keys: [ { name: 'id', optional: true } ],
regexp: /^\/user(?:\/([^\/]+?))?\/?$/i,
params: [ id: '12' ] }
http://expressjs.com/api.html#req.route
EDIT:
As explained in the comments, getting req.route in a middleware is difficult/hacky. The router middleware is the one that populates the req.route object, and it probably is in a lower level than the middleware you're developing.
This way, getting req.route is only possible if you hook into the router middleware to parse the req for you before it's executed by Express itself.
FWIW, two other options:
// this will only be called *after* the request has been handled
app.use(function(req, res, next) {
res.on('finish', function() {
console.log('R', req.route);
});
next();
});
// use the middleware on specific requests only
var middleware = function(req, res, next) {
console.log('R', req.route);
next();
};
app.get('/user/:id?', middleware, function(req, res) { ... });
I know this is a little late, but for later Express/Node setups req.originalUrl works just fine!
Hope this helps
This nasty trick using prototype override will help
"use strict"
var Route = require("express").Route;
module.exports = function () {
let defaultImplementation = Route.prototype.dispatch;
Route.prototype.dispatch = function handle(req, res, next) {
someMethod(req, res); //req.route is available here
defaultImplementation.call(this, req, res, next);
};
};
req.route.path will work to get the path for the given route. But if you want the complete path including the path of the parent route, use something like
let full_path = req.baseUrl+req.route.path;
Hope it helps
You can take a look at Router().stack, which has all the routes defined. In your middleware you need to manually compare the available routes with the one called to define actions.
I have the following code :
app.get('/payment', function(req, res) {
// do lots of stuff
});
now I want to add the following :
app.post('/payment', function(req, res) {
req.myvar = 'put something here';
// now do the same as app.get() above
});
Obviously I want to reuse the code. I tried doing next('/payment') inside the post handler and put it above the get handler, but no luck, probably because they are different VERBs.
What are my options ?
Thanks.
Just lift out the middleware to its own function and use it in both routes.
function doLotsOfStuff (req, res) {
// do lots of stuff
}
app.get('/payment', doLotsOfStuff);
app.post('/payment', function(req, res, next) {
req.myvar = 'put something here';
next();
}, doLotsOfStuff);