I'm just getting started with express.js and am failing to understand how one defines discrete "pages" (in the traditional sense) that one can link to internally.
I'm using Jade as a template engine and I see how it pulls the various components together and references them in the app.js (which is what is initially invoked by npm) so that, in effect is my "index". Would be great to see a tutorial on what one does to then build out pageA, pageB, pageC so that they can be linked to via <a href="pageA.html"> (or the Jade equivalent).
I'm assuming this is possible, right?
Express.js itself does not offer URL generation, only a built-in router.
You would need to use an additional package to perform URL generation, or build it yourself. Maybe you find something fitting in this question's answers: URL generation for routes in express
If you do not care about route generation and want to "hard code" the URLs, you would need to add a route for each static page, like this:
// routes.js
app.get("/pageA.html", function(req, res, next) { res.render("static/page_a", { templateLocals: "here" }) };
app.get("/pageB.html", function(req, res, next) { res.render("static/page_b") };
Or, if you have many of those pages, you could use a controller for this:
// static_page_controller.js
module.exports = function(pageTemplate) {
return function(req, res, next) {
return res.render("static/" + pageTemplate);
}
}
And use it like this:
// routes.js
var staticController = require("./static_page_controller");
app.get("/pageA.html", staticController("page_a"));
Related
I've got some troubles when start working with Next.js
Here is the deal. I have multiple filters, depends on them I make up URL. All of this URL's for one page.
It can be like:
/
/one
/one/two
/one/two/three
This nested is required. How can I create one handler for catch any of these URL's?
I use Express like this, but it doesn't help.
server.get('/*', async (req, res, next) => {
try {
app.render(req, res, '/')
} catch (e) {
next(e)
}
})
Thanks!
Use Dynamic routing like that :
pages/[one]/[two]/[three].js
cf:
Multiple dynamic route segments work the same way.
For example, pages/post/[pid]/[comment].js would match /post/1/a-comment. Its query object would be: { pid: '1', comment: 'a-comment' }.
https://nextjs.org/docs#dynamic-routing
Hope it's help.
New feature introduced in Next.js 9.5
Solution: Rewrites
See also: Redirects & Headers:
Announcing comment: https://github.com/vercel/next.js/discussions/9081#discussioncomment-48301
Besides that I am aware of some wildcard matching that nests paths deep in the default routing, but I feel Rewrites is a better solution in most use cases.
use npm next-routes in order to use path patterns (regex) to bind multiple urls to a page
Is there any way I can trigger a policy on a specific request method (e.g. DELETE) rather than on specific routes?
I'd imagine something like this:
module.exports.policies = {
'DELETE *': 'isAdmin'
}
My goal here is to expose the blueprint api to admins only, so that I can keep it in production, as it's a very useful tool for allowing third party scripts to add extra functionality.
I'm on Sails 1.0 right now.
One way to do that might be to add the check for the request method to the actual admin policy, however that doesn't quite seem like the best solution to me.
You can override the blueprint for all models for a particular method. You can do this for DELETE by creating a file destroy.js in /api/blueprints/ and then adding your code for what you want to do when a DELETE comes through:
module.exports = function(req,res, next) {
if(ACLService.hasPermission(req.user.acl, 'admin')) {
//Ok to allow delete here
} else {
return res.unauthorized();
}
};
This is how I've done it in the past, but looking at the docs for the just released SailsJS 1.0:
https://sailsjs.com/documentation/reference/blueprint-api
You may need to add this hook for overriding blueprints in 1.0
https://www.npmjs.com/package/sails-hook-custom-blueprints
Here is one method that you can use, I am not claiming that it is the right way, but you can consider it:
You can write your own hook. How to do this: https://sailsjs.com/documentation/concepts/extending-sails/hooks/project-hooks
Basically here is the solution with a hook:
1 Create a hooks folder under your api folder.
2 In the hooks folder create another folder - the name will be the name of your hook (say my-hook).
3 In api/hooks/my-hook create a file index.js and in it put the following code:
module.exports = function myHook(sails) {
return {
routes: {
before: {
'/*': function (req, res, next) {
if (req.method.toUpperCase() === 'DELETE') {
return sails.hooks.policies.middleware.isadmin(req, res, next); // note - your policy function name must be called here with all lowercase, otherwise it will not work.
}
return next();
}
}
}
};
};
Then in your isAdmin.js policy you can check if your user is an admin and if not:
return res.forbidden();
if it is admin:
return next();
How do you access application configuration settings inside a middleware function with express? For example say I have the following contrived example which is defined it's own module and I want to branch based on the results of a application configuration.
function fail(req, res, next) {
if (app.config.fail === true) {
res.json({'err': 'failed'});
}
return next();
}
What is correct way to handle this with express?
Well, if you wanna access app inside a middleware you can do that with req.app. As explained here
I hope this is what you were looking for!
I'm writing some rest API with Node.JS and Express. So for each API, I'd need to do all the usual stuff like parameter validation, authentication, authorization and then the actual business logic. Some sodo code to illustrate this:
router.get('/users', function (req, res){
async.auto(
authenticateCaller();
authorizeCaller();
validateParams();
doGetUsers();
)
})
This style certainly works but it makes the whole function very cumbersome by including a lot of extra pre-purpose codes. I know in web app programming, MVC has been introduced to separate UI, Module and Controller into different code groups, which is much cleaner. Is there any similar framework that can be helped to achieve this purpose?
Use middleware. Middleware is just a function that takes in three parameters:
function (req, res, next) {}
Call router.use() to register middleware before defining any routes. This will cause that middleware to be called before every route is executed.
These are all functions of middleware:
authenticateCaller();
authorizeCaller();
validateParams();
http://expressjs.com/en/guide/using-middleware.html
This is what I do.
Using Routes for Node.js Here I am making way for a folder named routes that has all the codes in it.
var routes = require('./routes');
var route_add_user = require('./routes/add_user');
Calling the function with the route here; .adduser is function name within that js file
app.get('/adduser', route_add_user.adduser);
define a function do your routine jobs
fuction auth(res,req,next){
authenticateCaller();
req.isAuthorized = authorizeCaller();
validateParams();
next();
}
router.get('/users',auth);
router.get('/users', function (req, res){
if( req.isAuthorized)
{..do some stuff here..}
})
This is one of the STYLE i was following to authenticate and use the API in express framework.
register.js
-----------
exports.addUser = function(req, res) {
// do something
};
exports.deleteUser = function(req, res) {
// do something
};
routes.js
---------
var register = require('./register');
router.get(‘/register’,auth, register.addUser);
router.get(‘/deleteUser’,auth, register.deleteUser);
// Better make it separate common file to reuse all the API
function auth(req,res,next) {
// do something to authenticate your API
}
I'm using nodejs with the mojito mvc framework.
Do I have access to some global variables from middleware? How can I use Y.mojito.models in middleware?
// ./middleware/mymiddleware.js
module.exports = function (req, res, next) {
// How to use Y?
//Y.log('fails');
//Y.mojito.models['MyModel'].fetch(function(err, data) {
// next();
//});
};
I strongly recommend not to try to do that. Those are express middleware, they are suppose to do a quick job, sometimes async job but generally, if the request is meant to be processed by mojito dispatcher engine, you should not try to access runtime components in a middleware.
That been said, there is an internal API (that again I strongly recommend not to use) that will give you access to the global Y which holds all the YUI modules at the server side. Something like this:
module.exports = function (config) {
// then `config.Y.mojito.models['MyModel'].fetch()` is available here
return function (req, res, next) {
next();
}
};
Aside from that, if what you're looking for is a way to share models, or expose global models, you should look at mojito-models-addon, expose method.
Again, the config.Y thing is private and we might change that at any time.
update: in mojito there are two types of middleware, the traditional express middleware and the mojito middleware, which will have to be prefixed with mojito-, and these are the one that should expose a function that receives config and returns a transitional express middleware. Without the prefix, it will just be called per requests without preparation.