difference between app.use('/users', usersRouter); and require(./routes/users)(app)? - express

In the express tutorial from mozilla,
https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website
they write
var usersRouter = require('./routes/users');
app.use('/users', usersRouter);
In other tutorials, they write something like this,
require('./routes/authRoutes')(app);
Are the two pretty much equivalent?

Without seeing the code for the other tutorials that you mentioned I cannot be sure exactly how they consume the app object that is passed to the imported code, but I suspect that whatever code is implemented in the .routes/authRoutes module simply connects a router object to the specified app object. This would most likely be done in the same way as the code that you provided from the Mozilla Express tutorial.
In both cases, a route handler is being defined and then registered as a handler for any routes that match the specified route. In the case that you mentioned that route would be the /users route. So the usersRouter object would have a number of route handlers defined, for example, for routes /abc and /def. So registering the usersRouter object as a route handler for the /users route would mean that the routes /users/abc and /users/def would be handled.

Related

Is there a way to apply middlewares on all of specific request method?

I have been working on a typescript project. I have created a middleware to check users' subscription and do not want to let users access PUT and POST routes. But I still want them to be able to access GET and DELETE requests.
I know that the following line applies the checkSubscription middleware to all the requests on the route.
router.use(checkSubscription)
I only want the middleware to run if the request type is PUT or POST.
I could do the following, of course
router.get("/endpoint1", controller1);
router.put("/endpoint2", checkSubscription, controller2);
router.post("/endpoint3", checkSubscription, controller3);
router.delete("/endpoint4", controller4);
Notice that the above PUT and POST requests run the checkSubscription middleware.
But if I could declare on the top of the route file to run the middleware on all POST and PUT requests, that would save a lot of work and time.
Any kind of help would be highly appreciated. Thanks!
You can restrict the middleware to PUT and POST requests by evaluating the req.method inside:
function checkSubscription(req, res, next) {
if (req.method !== "PUT" && req.method !== "POST") return next();
// Rest of your middleware code
}
This keeps the rule "this middleware is only for PUT and POST" local to the middleware, no matter how often it is referenced in other statements like router.use and router.post.
But if I could declare on the top of the route file to run the middleware on all POST and PUT requests, that would save a lot of work and time.
You can just do something like this:
router.put("*", checkSubscription);
router.post("*", checkSubscription);
This will only call the checkSubscription() middleware for all PUT or POST requests that hit this router.
The "*" will match any path that goes through this router, but you could use any particular Express route pattern/regex there that you want if you want it to match more than one path, but not all paths.
As it sounds like you already know, you can also control route declaration ordering to give some routes a chance to handle the request before the middleware gets a shot to run.
Since Express runs middleware (including route handlers) in order, you can place the routes for which you don't want to run the middleware first, then the middleware, then the routes for which it does need to run:
router.get(...);
router.delete(...);
router.use(checkSubscription);
router.post(...);
router.put(...);
It does require some diligence with regards to app maintenance, because developers need to understand that the order in which the handlers are declared is relevant.

How to inject a request (bypass HTTP protocol stack) in nodejs express?

Imagine this sample Express app straight from the documentation:
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(3000)
What is the idiomatic way to invoke the '/' endpoint programmatically from a different point in the same application code? Assume that I already removed the last line app.listen(3000).
The reason for this is that I want to take something like express-pouchdb and write an adapter for a different wire protocol, but leveraging the extensive routes already defined. I want to invoke these routes directly from js code without going over the network.
The application has dozens of routes already defined so changing each one to direct function calls as suggested in the first comment is not an option.
UPDATE:
I tried calling app.route.dispatch() but nothing comes back on the rsp object.
Your question is a duplicate of this answer: Is it possible to call Express Router directly from code with a "fake" request?
You can use run-middleware module exactly for that. You create an express app a usual, and then you can call the app using your parameters

ExpressJs and POST from external source to my income router, how to get data

I'm getting my hands dirty with Node and expressJS, new with Node and ExpressJS, and there something that I can't get right.
There is a service that POST data (json format {}) to my "income" router, the thing is, a logger helper that check all routers is printing (console.log) the incoming data, but inside the router, I can't get anything (i can't do a console.log for example), not req.body, there is "nothing", just the res.sendStatus(200) that is required for (https://cloud.google.com/pubsub/docs/push).
Any idea about why this happens?
Thanks
There could possibly be some middlewares attached that are actually doing the job, while the router is merely printing the logs. In this case, middleware are attached to be functional well before the code in route gets executed.
Check for app.use or router.post('SOMEPATH',MIDDLEWARE1, MIDDLEWARE2)
ExpressJS's core strength is to modularise the code using middleware.

Adding property to the request using Node and Express

I have a MEAN application, and I'm handling authentication using passport. What I want to do is exactly what happens to the user on the passport, which can be accessed from the request like req.user. I have not found any solutions to reach that result. Can you give me any advice?
You can add properties to the request or response objects by creating a middleware and using it in your app. E.g.
// Defining middleware
function myMiddleware(req, res, next) {
req.myField = 12;
next();
}
// Using it in an app for all routes (you can replace * with any route you want)
app.use('*', myMiddleware)
Now all your request objects in your handlers will have myField property.
To add extra properties to the request and response object you need to extend the response and request interface.
index.d.ts files are used to provide typescript type information about a module that’s written in JavaScript.For express, the index.d.ts is present inside the #types/express folder inside the node_modules folder.
Use this link-
https://dev.to/kwabenberko/extend-express-s-request-object-with-typescript-declaration-merging-1nn5

Laravel resource with parameter causing other routes to throw error

I am running into this issue where if I define a param in that first route, the second throws this error:
"Route pattern "/browse/{brand}/{{brand}}" cannot reference variable name "brand" more than once."
Route::resource('browse/{brand}', 'BrowseController');
Route::group(array('prefix' => 'service'), function() {
Route::resource('authenticate', 'AuthenticationController');
});
If I take out the param, of course that breaks the browse route, but then the auth route works.
Does anyone know the reason for this?
The reason is because Route::resource creates several (RESTful) route handlers for you in the background for the controller you specify:
http://laravel.com/docs/controllers#resource-controllers
Take a look at the table called: Actions Handled By Resource Controller
You can see that Laravel will already handle routes for you that take parameter that you can use to implement browsing.
I don't think that the intended usage for Route::resource is to be parametrized like you are trying to.
Of course you can always implement additional routes if those do not match your needs.