Everyone. Are the routes used in the sites are makes with directories or with requests, like Express?
For example: https://stackoverflow.com/questions/ask
The page ask, is in a directory with the name questions or it's made with requests?
Examples:
With Express:
app.get('/questions/ask', async(req, res) => {}
With folders:
https://i.stack.imgur.com/61cwh.png
And the page ask inside the folder questions.
https://i.stack.imgur.com/koabp.png
If I do this, I can access the page ask with "https://domain/questions/ask.html"
I'd like to know how to do routes correctly.
Related
I am pretty new to the node.js and express.js landscape. However I have been trying to wrap my head around the code behind creating a site (20+ pages for example) in express.js without the code getting pretty large.
A route, when using a view engine, points the incoming request to index or whatever page they requested. After running the default express-generator with the view engine set to HBS you get something like
app.use('/', index);
This points to the index.js file under the routes folder that contains something like
router.get('/', function(req, res, next){
res.render('index', {title: 'Express'});
});
And that then renders the index.hbs file to show what I want on the page.
My problem is this. Would you have to have a route for each page you wanted like a profile page, login page, about page, etc? If so wouldn't this create a lot of lines of code in routes if you had 20+ routes? Example would be in the app.js
app.use('a', a);
app.use('b', b);
...
app.use('z', z);
then each would require a corresponding route js file.
I assume there is a cleaner way of doing routing or perhaps I am over thinking this?
Any light on this concern/question of mine would be amazing.
In my express servers I break routes into different sections called "components" Each components can correspond to a give page if you're doing server-side rendering or it can correspond to a set of API routes.
Each component can have controllers to handle each route, and each controller can borrow from a handful of reusable actions.
Here's an example of an express server component I made(this example is for a set of API routes but the same architecture can be used for sets of hbs server-side rendering routes):
https://github.com/AkyunaAkish/react-redux-node-express-todo-list-boilerplate/tree/master/server/components/todos
It depends on how similar your routes are:
If they basically all have the same functionality, I'd put them in the same file.
If there are slight variations, I'd create a separate class containing the core functions, and then call to what ever is needed separately.
If they are completley different, put them all in separate files
This will give you a solid outline of how to do each:
How to include route handlers in multiple files in Express?
Node.js: Configuration and routes in a different file
How to include route handlers in multiple files in Express?
Generally, you make route files around areas of concern, though a given router can define whatever endpoints make sense. So for example, let's say your site has several pages that are fairly static (e.g. your "about" and "index" examples, and then several that are all based on blog entries (creating, listing, viewing, etc) and then several around users (user profiles and so on). You would probably create one router for each set of things, e.g.:
// ./routes/index.js
router.get('/', (req, res) => { res.render('index', {title: 'Express'}); });
router.get('/about', (req, res) => {res.render('about', {title: 'Express'});});
// etc
conceptually, you could use that more simply to pull the "index" or "about" values from the URI, but I'm assuming you'll do other things like assigning variables and such.
Then in another file
// ./routes/blog.js
router.get('/blog', (req, res) => {
// do whatever to fetch info fromt eh DB and render it...
});
And so on.
My application currently serves fine making calls with Express, but I have a page now rendered by:
app.get('/user/:username', function(req, res){
serve html page (no problems)
}
and from that page, I'm making a request for
return $http.get('/api/user/:s').success(function (resp) {
stuff...
}
which is returning a 404 not found.
The call is in my Express app.js as
app.get('/api/user/:username', routes.api.getDBUser);
and I've been stumped on this problem for ages now. I feel like the issue is from something related to the URL.
EDIT:
app.use("/user", express.static(path.join(__dirname, 'static'))); //serving statics for localhost/user paths
app.get('/api/user', authentication.isAuthenticated, routes.api.getUser);
app.get('/api/users/:username', routes.api.getDBUser);
app.get('/api/user/friends', authentication.isAuthenticated, routes.api.getUserFriends);
app.get('/api/user/history', authentication.isAuthenticated, routes.api.getUserGameHistory);
is all the routes related to the user here. I'm not sure if this has something to do with it, but accessing a routing call when the url is something like localhost(port)/something, it's okay. The URL at this particular page I'm trying to make the call from is localhost(port)/user/something
For some strange reason, some changes on my route settings (MEAN environment, Node v0.12.2 and express 4) don't show effect any more!? Particularly instructions where I respond to client requests using ".sendfile()".
app.get('/', function(req, res){
res.sendfile("/public/index.html"); // <-- trying to exclude or change this
console.log("debug message"); //added later, never shown!!
});
Excluding or altering the sendfile instruction in the example above doesn't change anything - index.html is alyways being delivered upon request. Not even simple debug messages like console.log are shown any more?! Here's what I checked:
restarted Node.js server and computer several times
checked for duplicates of routes.js file
checked for duplicates of home route ("/")
cleaned browser cache
even deleted the ENTIRE route, site still delivered upon request!?!?
Maybe there is some kind of server-side cache that needs to be wiped?! I got no idea any more of what's wrong. Suggestions anyone?
There are changes in express 4 with respect to express 3. In express 4 we have got a new method app.route() to create chainable route handlers for a route path and a new class express.Router to create modular mountable route handlers. For more details ref: Moving to Express 4 What you can do is try using code in following order:
app.route('/')
.get(function(req, res) {
res.render('index');
});
And its also good serve static files by adding:
app.use(express.static(path.join(__dirname, '../public')));
Good luck...:)
I am developing a web application with the mean.js boilerplate code. Recently I added a view to my application (the 'analysis' page) by creating an analysis module and added some route logic with the following code.
//Setting up route
angular.module('analysis').config(['$stateProvider',
function($stateProvider) {
// Projects state routing
$stateProvider.
state('imageAnalysis', {
url: '/image_analysis',
templateUrl: 'modules/analysis/views/tools.client.view.html'
});
}
]);
This works just dandy, I can go to homepage.com/image_analysis and see my tools.client.view.html page. My goal now is to have this page only visible to user who are logged in. My first approach to this was to check if the user was logged in the angular routes logic, this has proven to be difficult for me. I also read that check authentication in the front end is very unsafe. So I've decided to check if the user is logged in with Express routing.
Here is an example of what Express routing looks like for one of my other AngularJS modules
module.exports = function(app) {
var users = require('../../app/controllers/users.server.controller');
var projects = require('../../app/controllers/projects.server.controller');
// Projects Routes
app.route('/projects')
.get(users.requiresLogin, projects.list)
.post(users.requiresLogin, projects.create);
app.route('/projects/:projectId')
.get(users.requiresLogin, projects.read)
.put(users.requiresLogin, projects.hasAuthorization, projects.update)
.delete(users.requiresLogin, projects.hasAuthorization, projects.delete);
// Finish by binding the Project middleware
app.param('projectId', projects.projectByID);
};
Notice the users.requiresLogin function which check if a user is logged in and redirects the user to the signin page if they are not. I want to take advantage of this function. Some things I dont quite understand in the boilerplate code are what is the purpose of app.route()? I think this might be a middleware but I am not sure what it does.
Here are some attempts I've take taken at messing around with express routing. These attempts are in my analysis.server.routes.js file that I created.
Attempt 1
module.exports = function(app) {
var users = require('../../app/controllers/users.server.controller');
// analysis routes
app.get('/image_analysis', function(req, res) {
console.log('helloworld');
console.log('helloworld');
console.log('helloworld');
console.log('helloworld');
console.log('helloworld');
console.log('helloworld');
});
};
I thought this would log 'helloworld' when I access the image_analysis page, but it didnt appear to do anything.
Attempt 2
module.exports = function(app) {
var users = require('../../app/controllers/users.server.controller');
// analysis routes
app.route('/image_analysis')
.get(users.requiresLogin);
};
Based on the other code, I thought this might work to require login for the analysis page. But it did nothing.
Any help would be much appreciated! Thanks everyone, I am struggling to grasp express routing at the moment and stackoverflow has been a tremendous help.
I don't have a solution, or not at least at this moment that I could think of.
However I can explain to you how things work and why a solution might not be trivial.
what is the purpose of app.route()
This defines your routes.
app.route('/projects/:projectId')
.get(users.requiresLogin, projects.read)
.put(users.requiresLogin, projects.hasAuthorization, projects.update)
.delete(users.requiresLogin, projects.hasAuthorization, projects.delete);
What that code does is when a client requests a URL like one of the following
GET /projects/5562ff08de4f70180bba3083
PUT /projects/5562ff08de4f70180bba3083
DELETE /projects/5562ff08de4f70180bba3083
it first executes that middleware function users.requiresLogin,
which is defined to be common in all methods (.get .put .delete)
and then their respective middlewares in that order
projects.read | projects.hasAuthorization ...
On how Angluar routing works in contrast to Express routing:
Angluar routing is all done client-side. It's all achieved through Javascript
changing the addressbar url and displaying the view attached to that route.
Your Angular app is served by the server through a single (Express) route - / (homepage)
So again, your entire Angular app loads thorough just 1 route on the server-side,
and then Angular takes over the routing to client-side through it's own ui-router.
Now it must be starting to seem obvious that it's not trivial to have server-side authentication check
interfere between client-side routing.
You can only have server-side authentication work with routes that server actually is in control of serving.
Those are mostly just your API routes, in your case.
Attempt 1
app.get('/image_analysis', function(req, res) {
console.log('helloworld');
I thought this would log 'helloworld' when I access the image_analysis page, but it didnt appear to do anything.
It indeed should have! Unless.. there's a route that comes before it that already serves all requests
app.get('*', function(req, res) {
res.send(angularApp); // your angular app is served here
});
// No request would *need* to go beyond past this point
// because it already got served above
app.get('/image_analysis', function(req, res) {
// so this isn't reached.
console.log('helloworld');
});
So that's why it doesn't work.
I am starting to learn Node.js, using Express with Jade and Mongoose as my default toolbox. I used to develop in PHP, migrated to Python, and learned MVC through Django. Having a large client-side JS game and some inspiration from Mozilla.org, I am willing to make a multiplayer game -- and saw this as a noncommercial opportunity to learn Node: I can take my time with it.
However, I ran into a problem. I'm not trying to write an MVC system on my own, just to separate my site's "apps" like most MVCs do. The question is probably basic -- having this chunk of code:
app.get(/^blog/, function(req, res) {
require("./blog")();
});
... I understand the basics of Node/Express' URL masking, however I need to pass the rest of the URL string (everything that's after mysite.com/blog) to another URL parsing script, inside the blogapp.
I googled around for a while and couldn't find a good solution. I even found a full tutorial on building an MVC scheme in Node and Express written for an older Express version, but that's a bit over the top for now. Can you provide me a simple solution?
I think blog/index.js should look something like this:
module.exports = function(urlstring) {
if(urlstring.indexOf('post') != -1) {
// do stuff...
}
else if(urlstring === '/') {
// return home.jade or something
}
};
I hope I'm being clear. Thanks in advance!
With express there is no need to parse your URLs on your own. I guess you'll want to build your blog URLs somehow like this
/blog Show a list of blog posts
/blog/post/1 Show blog post with id '1'
With express 4 you can set up a router for your blog path or a mounted app. Mounted apps allow you to let an app handle all sub URLs of a base URL path. See the express documentation for more detail.
I'd like to demonstrate how you can use the express 4 router together with the mounting feature of express to build blog routes.
// Set up express app
var app = express();
// Set up a router
var router = express.Router();
router.get('/', function(req, res) {
// Show a list of blog posts
}
router.get('/post/:id', function(req, res) {
// Show a single blog post
}
// Mount router
app.use('/blog', router);
A benefit of this solution is that your routes registered in the router always get relative URLs with out the /blog prefix so you may reuse your blog routes in some other project under a URL like /companyblog.