Express routing and URL parsing when using separate modules - node.js

I'd like to be able to parse a url query for data and use it in my response. In my app file I have the following:
var entry = require('./routes/entry');
app.use('/entry*', entry);
in my route file:
router.get('/:name', function(req, res) {
res.send(req.params.name);
});
module.exports = router;
Currently I am getting a 404 error.
I'm wondering how I can get a name parameter out of the url. So if someone were to type .../entry/example then the response would be "example."
A lot of my confusion stems from what should be handled by the router and what the app.use should have as its URL parameter. Thanks so much!

Remove the asterisk * from /entry and it should start working as expected. I created a local express application and inserting the asterisk causes the same issue.

Related

Problem using Nodejs / Express routing paths

I am a long time programmer but I'm new to Node and have a simple question about routing paths in Express which I cannot get to the bottom of.
I've developed a very simple app using node/express and MySql. I have then split up my GET and POST routes in the app just for convenience. I am using the route '/posts' at the app level and the sub route '/submit-form' in my router() which is the URL my form submits to.
I'm obviously doing something stupid because it doesn't work, I get the cannot POST message. If I use the full URL in the app and in the router then it works fine so there's nothing wrong with the code I think, only with my understanding of how express does routing.
Any advice appreciated.
A router should be used with the .use() method. Therefore, you should use the following in your app.js file
app.use('/posts', PostRoute)
When the nested router (on /posts) will handle the request, it will now based on the nested route declaration which HTTP method should match
app.js
const app = express();
app.use('/user', require('./routes/user'))
then inside the user;
const router = express.Router({});
router.post('/login', (req,res,next) => {
});
module.exports = router;

issues routing express routes [duplicate]

This question already has an answer here:
Node.js and express : Routes
(1 answer)
Closed 4 years ago.
I am getting an error indicating.
Cannot GET /todoListItem
Not sure why I am getting this error because after researching and reading documentation my routes as shown bellow look correctly defined.
//#route GET to do list page route
router.get('/showToDoList', function(req, res) {
res.redirect('/todoListItem');
});
module.exports = router;
in my server.js I am implemting my app use in this manner.
var indexRouter = require('./routes/index');
var todoListItemRouter = require('./routes/todoListItem')
//Bodyparser MiddleWare
app.use(bodyParser.json())
// Add to do list routes to middleware chain.
app.use('/', indexRouter);
app.use('/showToDoList', todoListItemRouter);
in my todoListItem.js I am calling my controller.
//#route GET all do list items from user.
router.get('/todoListItem', todoList_controller.todo_lists)
I am not sure why I would getting that error shown above. my file dir is implemented
-routes
-- index.js
-- todolistItem.js
in my server.js file I am doing the routing logic. Any help to understand my issue will greatly be appreciated. this is my github repo for more info
https://github.com/OlooAllaN/ToDoList-Project
You cannot GET that file because there is no route defined for /showToDoList.
app.use('/showToDoList', todoListItemRouter); tells Express to point all requests matching "/showToDoList" to this router. Any routes defined in todoListItemRouter are accessed by using "/showToDoList/route1", "/showToDoList/route2", "/showToDoList/showToDoList".
The correct way to do this, is to edit your route inside your todoListItemRouter to this:
//#route GET all do list items from user.
router.get('/', todoList_controller.todo_lists)
This will accomplish the affect that you are looking for. Please see Express Docs for more information about using external routing files.

Register new route at runtime in NodeJs/ExpressJs

I want to extend this open topic: Add Routes at Runtime (ExpressJs) which sadly didn't help me enough.
I'm working on an application that allows the creation of different API's that runs on NodeJs. The UI looks like this:
As you can see, this piece of code contains two endpoints (GET, POST) and as soon as I press "Save", it creates a .js file located in a path where the Nodejs application is looking for its endpoints (e.g: myProject\dynamicRoutes\rule_test.js).
The problem that I have is that being that the Nodejs server is running while I'm developing the code, I'm not able to invoke these new endpoints unless I restart the server once again (and ExpressJs detects the file).
Is there a way to register new routes while the
NodeJs (ExpressJs) is running?
I tried to do the following things with no luck:
app.js
This works if the server is restarted. I tried to include this library (express-dynamic-router, but not working at runtime.)
//this is dynamic routing function
function handleDynamicRoutes(req,res,next) {
var path = req.path; //http://localhost:8080/api/rule_test
//LoadModules(path)
var controllerPath = path.replace("/api/", "./dynamicRoutes/");
var dynamicController = require(controllerPath);
dynamicRouter.index(dynamicController[req.method]).register(app);
dynamicController[req.method] = function(req, res) {
//invocation
}
next();
}
app.all('*', handleDynamicRoutes);
Finally, I readed this article (#NodeJS / #ExpressJS: Adding routes dynamically at runtime), but I couldn't figure out how this can help me.
I believe that this could be possible somehow, but I feel a bit lost. Anyone knows how can I achieve this? I'm getting a CANNOT GET error, after each file creation.
Disclaimer: please know that it is considered as bad design in terms of stability and security to allow the user or even administrator to inject executable code via web forms. Treat this thread as academic discussion and don't use this code in production!
Look at this simple example which adds new route in runtime:
app.get('/subpage', (req, res) => res.send('Hello subpage'))
So basically new route is being registered when app.get is called, no need to walk through routes directory.
All you need to do is simply load your newly created module and pass your app to module.exports function to register new routes. I guess this one-liner should work just fine (not tested):
require('path/to/new/module')(app)
Is req.params enough for you?
app.get('/basebath/:path, (req,res) => {
const content = require('content/' + req.params.path);
res.send(content);
});
So the user can enter whatever after /basepath, for example
http://www.mywebsite.com/basepath/bergur
The router would then try to get the file content/bergur.js
and send it's contents.

Express not catching request to '/'

I have a quite bizzare issue - somehow, Express does not capture my request to my root route.
My Route File looks to following:
'use strict';
var errors = require('./components/errors');
var auth = require('./controllers/auth');
var ensureLoggedIn = require('connect-ensure-login').ensureLoggedIn;
module.exports = function(app) {
// Insert routes below
// All undefined asset or api routes should return a 404
app.route('/:url(api|auth|components|app|bower_components|assets)/*')
.get(errors[404]);
app.route('/login')
.get(auth.login)
.post(auth.loginUser);
app.route('/logout')
.get(auth.logout);
// All other routes should redirect to the index.html
app.route('/*')
.get(ensureLoggedIn('/login'), function(req, res) {
console.log("req to /");
res.sendfile(app.get('appPath') + '/index.html');
});
};
So what happens:
I request '/' and it sends me directly to my root and the app runs. Except: It does not require me to login, and also the Log Output does not show that any request has been made.
If i request '/users' (Angular Route) it redirects me to '/login', as expected and then continues on its path.
Any idea what would be causing this behavior?
Are you exposing any static assets with express? If you are and you require your routes after you expose the assets, the request to "/" will just land in your public folder and do nothing.
Does this help? Could you post your server.js?
I ran into this issue earlier and it was driving me nuts.
It seems like it's related to the filename of the 'main' Page being served, before Angular takes over.
Originally, the file was names index.html which, as it seems like, prompted Node to serve it by default - Which is expected behavior, if no routes interfere.
After renaming the main file to application.html and changing the serve asset - all is well, problem solved.
I am still unsure though, why the Route would not fire and the index would overwrite it.

URI bind Express.js

Hello I want to bind the URI of my app, for example lets imagine this scenario.
I am running express app on port 3000,
nginx on port 80, proxying requests of URI api to port 3000
And have this route on express
// Home
app.get('/', function(req, res) {
res.send('Hello!');
});
If I try access from localhost:3000 I get Hello! in my browser (that's expected),
but if I try to access from localhost/api I will get an error, of course he can't find the route I'm tryng to access.
If I change app.get to app.get('/api/... it works as expected, but this isn't what I want... I would need to prepend api in every route, there must be another way to do this, something like:
URI binding
URI filter ??
I read the documentation but can't find anything to solve my problem, and I'm thinking of doing a package that does URI bindings on express to solve this problem.
See my answer here for a solution that lets you point every request matching a leading /api to a particular express app. In the linked case, the user wanted to do some things without the leading fragment. You could leave out the app.use(app.router) for the main express app since you only care about the /api/ routes.
<snip>
var http = require('http');
var express = require('express');
var desktopApp = express();
var mobileApp = require('./mobile.js');
desktopApp.use('/mobile', mobileApp)
desktopApp.use(desktopApp.router);
</snip>
Also I am pretty sure that you can actually rewrite request.url yourself. I have never tried this so I can't promise it works! see docs http://expressjs.com/4x/api.html#req.originalUrl Also be sure to put this at the very top of your routing functions, so it is executed before any subsequent routes.
app.all('*', function(req, res, next){
req.url = req.url.replace(/^\/api/, '');
//the regex replaces leading /api with empty string
//req.originalUrl will keep the old url
next();
});

Resources