middleware depend on each other, for example methodOverride() checks
req.body.method for the HTTP method override, however bodyParser()
parses the request body and populates req.body. Another example of
this is cookie parsing and session support, we must first use()
cookieParser() followed by session()_.
I wonder how can we know which middleware should be use before another? I wonder if there already exist an ordered list (a list with all middlewares in correct working order) somewhere?
The list of middleware on connect's home page is in the correct order, though it doesn't explicitly call out dependencies.
Related
I need to pass variable to a Twig layout about user country and language.
These datas are determined from the route, so I can't get them before routing is done.
I could set them from the route callbacks but code would be repeated in each route.
So I added a middleware to routes. It reads request arguments and sets variables (through $twig->getEnvironment()->addGlobal(...)).
I am not fully convinced, is there a better way to achieve this?
thanks
Routes in Express:
/search/:company-name
/search/:category-name
I can see that first one is fired for both requests so they are same, but is there a way to solve this without involving for example:
/search/company/:company-name
/search/category/:category-name
Yes, they are the same.
The router just see a route that starts with search/ and ends with a wildcard. The only thing that change is the name you give to that wildcard, which doesn't matter for the router, it's still the same URL.
You can solve this by either changing the route, or you can parse the route argument (the wildcard) and do something different depending on its value.
You could use a query instead of a param.
Your urls would be:
/search?company=company-name
/search?category=category-name
Your route is /search and you use req.query instead of req.params.
It's either that,
or your solution of changing the route,
or somehow parsing the parameter to decide whether it's a company or a category
or changing your route to a post and using key-value pairs in the post body
I want to make HTTP requests with some known cookie key-value pairs (e.g k1=v1; k2=v2; ...) using wreq, but can't find a convenient way of creating them.
Because Cookie has many fields, I'd prefer a smart constructor than having to fill all fields on my own.
By browsing documents, I find generateCookie to be the most promosing one (and that's also the only one I've found that returns a Cookie): I can create SetCookie and all I need are just key value pairs. But we don't have a Request to feed it as the second argument. Using http-client alone, one can do parseUrl to create one. But in wreq I feel the author want to hide Request from user and I can't find a function that gives us direct access to it.
So my question is: are there better ways to create cookies in wreq than using Cookie constructor?
I'd probably fork the generateCookie implementation, as it looks like the Request argument is used only to validate the fields.
http://hackage.haskell.org/package/http-client-0.4.26.2/docs/src/Network-HTTP-Client-Cookies.html#generateCookie, except for default cookie path, as SetCookie has Maybe path.
Given a nodejs, mongoose, mongodb, expressjs setup, we have permission/security related routes that validate a particular request. For example:
permissionUtils.checkStudentWritePermissions = function(req, res, next){
//load this student from the mongoose db
//ensure the current user has permission to update this student
}
server.put("/api/student/:studentId/enroll",
permissionUtils.checkStudentWritePermissions, function(req, res, next){
//load student from the database, validate the changes
//update student in mongodb, send new version back to user
});
The middleware is useful because we're ensuring the current user has the rights to update the student in every case. (Code re-use etc.) You'll note that in both examples I'm loading the student from the mongodb. Is there an accepted pattern to avoid this double-loading? Some kind of request-cycle cache or a slick way of passing the model around?
There are many different solutions here. I'll try to quickly give you a few.
1) First of all, separate your code to actually fetch (and any pre-processing you need) into a function in a user model. Second, if you don't have a user model, an MVC approach will make your code much easier to follow when it grows. From here, you could easily cache the response on the first call, and just serve it back on the second without re-fetching from the database. Look at something like Memcached or Redis.
2) While it may not be convention, you could pass the object from the middleware into your main function. If you do choose to do this, document what you did clearly so that people in future understand why your middleware is calling next(req, res, obj), and don't 'fix' it by replacing it with just next().
3) A third approach would be to save the object into the res.locals (I believe that's what its called now). These are values that Express keeps for the current request. Saving it there would be similar to a cache, however would only be accessible during that request. On subsequent requests, the object would have to be refetched.
Note that whatever of these options you choose, implementing some sort of cache for commonly accessed objects will, in almost all circumstances, speed up your application.
I am looking for some documentation on the app.get function of express.js.
app.get(
'/path',
middleware(),
function(req, res) {
res.redirect('/');
}
);
The example above takes three parameters. The normal docs only show two. I'm interested in what this middle param does and how to use it.
The docs for that are part of the app.METHOD documentation, where get is one of the supported HTTP methods.
The second, optional parameter, is called middleware (and you can pass an array of middleware functions). This is a function that's called before the third parameter callback (the actual route handler) and the responsibility of a middleware function is to allow your code to follow the DRY (don't repeat yourself) principle.
Example of middleware functions are permissions checks, access validations, validation of sessions (if user is not in logged in, take him to a log in page), and such.
Since several routes might desire the same behavior, you use a middleware so that you don't have to write the same code several times.