I have an express application with the following routes:
// Get category by id
innerRouter.get('/:id', categoriesController.getById)
// Get all categories along with their subcategories
innerRouter.get('/withSubcategories', categoriesController.getAllWithSubcategories)
The problem is that express doesn't seem to distinguish between the two, for example with this request:
http://localhost:3000/api/categories/withSubcategories
Express will actually invoke categoriesController.getById and not categoriesController.getAllWithSubcategories.
I know i can create a single route and then check for req.params.id, but i want to believe that there's a more elegant way of doing this, is there?
Express is sensitive to the order with which you define routes, so moving /withSubcategories above /:id will solve the issue. However, you should probably move /:id to something like /category/:id since having a match-all in the root path is inadvisable.
Related
I'm using wildcard-subdomains to handle wildcard subdomains in my express app, so something like subdomain.localhost:3000 would enter the router as /s/subdomain/.
I want to match the main index url of any subdomain, but none of the pages under it.
Essentially, I want a route that would match /s/subdomain/ but not /s/subdomain/page/ or /s/subdomain/page (for clarity, "subdomain" is just a placeholder for any wildcard domain)
This is simple to do in regular regex, but I am unable to use the dot modifier due to express using path-to-regexp. It would be possible for me to generate a router for each user, but I would really like to use something cleaner if it's possible.
Dang, i'm pretty stupid. /s/:target/ works perfectly fine, and creates a neat little target parameter to make things a bit easier. I was totally overcomplicating things by trying to use regex.
I am looking at some code from someone else for learning purposes. The way they're mounting routes is vague to me.
app.use('/dist', express.static(path.join(CURRENT_WORKING_DIR, 'dist')))
// mount routes
app.use('/', userRoutes)
app.use('/', authRoutes)
app.use('/', postRoutes)
The confusing part for me is how they're using '/' and using app.use. I'm used to doing it with app.get() and on top of that you specify the route instead of putting '/' everywhere. How does this work? Is this better practice?
The repo I'm looking at is https://github.com/shamahoque/mern-social/tree/master/server
Writing routes directly can be confusing and difficult to manage if there are large number of routes. So according to MVC pattern, the application is divided into modules/logical blocks based on functionalities they perform. For example, a simple hospital management system can have authentication, billing, payroll , medical-stock , patients etc modules (imaginary). If you are building application using MVC pattern, the common practice is to write controller for each of the module. Express provides something called middleware also called as Router to attach these controllers to respective API routes (Imagine it as a sort of map that connects each route to respective controller).
Once you define routes for each of these modules through middleware, you use those routes with your application. These routes handle requests and send parameters to controller to process.
You can learn how to use Middleware and Routers here : https://www.tutorialspoint.com/expressjs/expressjs_routing.htm
Regarding quality of code, dividing the code into modules and using routers to connect them is less tedious for others to understand. It also provides a good view of the application and it becomes easier to add new modules / functionality.
You can read more about building production-ready express app here :
https://www.freecodecamp.org/news/how-to-write-a-production-ready-node-and-express-app-f214f0b17d8c/
I am starting work on an existing Node/Express/Mongoose project -- I am currently going through the code and trying to understand how it works. The Express routes are being generated dynamically, that is to say there are functions that set up the routes -- the http method, the path to resource, the Express app, etc are passed into those functions as parameters and the routes are constructed at runtime. There are many nested functions -- it's a complex project -- but it all ends up with the line
app[method](path, requireAuthentication, requireAdminAuthentication, validateRequestBody, done);
which sets up the route.
Is there any way to debug a route after it's been constructed? That is to say, if I wanted to put some debug() statements in the POST route for '/widgets', but that route doesn't exist anywhere in the code, and in fact doesn't exist at all until after the app starts, where do I put the statement?
Well, you can use the DevTools and can get into the Sources tab and then press CTRL+O and then if you start typing the file name (which contains your dynamic routes) you can find it listed over there, just open it and set the breakpoint(s) where ever it is required.
Hope this helps!
I have the following Node Express routes...
get('/api/dogs')
get('/api/dogs/:id')
get('/api/dogs/breeds')
You can probably see the problem already. The routing gets confused when calling the 'breeds' route thinking I am trying to call the 'dogs/:id' route.
Is there a way to get around this? Or should I just create a unique route, something like 'api/dog-breeds'? I'd like to keep them all under the same resource because I am using the Express' modular 'router' object.
In express, I can something like this to have a static server, with directory index pages:
app.configure(function() {
app.use('/mystuff', _express.static(__dirname + "/whatever/stuff"));
app.use('/mystuff', _express.directory(__dirname + "/whatever/stuff"));
});
I would like to modify the directory index pages, by giving them different css, adding some javascript, and maybe altering the html. I prefer use as much of the existing functionality if possible, but if it is easy to just replace the whole directory middleware with my own code, that's an option. Not sure where to start with this. Of course, I don't want to actually edit code in the express or connect modules.
BTW, one reason for this is to workaround a bug I mentioned here: How do I set up static serving in Express with an arbitrary start path?
As you said in your comment, the express.directory functionality comes from Connect middleware; however, there doesn't seem to be a way to set a custom file.
As an alternative solution, you could fork Connect, change the files (located at lib/public/directory.html and lib/public/style.css), use your fork as a dependency, and do:
var connect = require('connect');
app.configure(function() {
app.use('/mystuff', connect.static(__dirname + "/whatever/stuff"));
app.use('/mystuff', connect.directory(__dirname + "/whatever/stuff"));
});
Instead of the express ones. I just tested this (by editing the files in node_module), and it worked.
EDIT:
Actually, you could probably just grab directory.js from connect and modify it and put it in your app and require() it, and then use yours instead. I haven't tested this, but I can't see why it wouldn't work.