Right now I have two routes, invoking the same method.
Let's say the method's name is myMethod
And two routes are / and /:params
router.get("/", myMethod);
router.get("/:param", myMethod);
Since in both cases I have to invoke the same method, I want to use a single route to invoke the myMethod. Something like this,
router.get('/' or '/:param', methodName);
If it is possible, then how can I do this?
You can use an array :
router.get(['/', '/:param'], myMethod);
Related
In fastify, is there a way I can add an alias to a route/ path? Basically, having two paths be handled the same way. This is useful for migrating an APIs.
I understand that I can abstract the handler function into a named function, and pass that function to both routes. I am just wondering if there's another way to do so?
No, there is not the feature to set an array of routes to one handler (here the registration logic if you would like to add this feature).
I would suggest registering routes like this:
['/', '/alias'].forEach(path => {
fastify.route({
method: ['GET'], // you could define multiple methods
url: path,
handler: mySharedHandler
})
})
When using Express normally you use app.post('/path') or app.get('/path') to define routes.
Does Express also provide a function to define routes like this app.route('POST', '/path') (where route is the function I'm looking for)?
You can programmatically select method with bracket notation. For example:
app['post']('/path')
app['post']('/path-2')
app['get']('/path')
I'm just trying to get a grasp of what middleware refers too. At first I thought it was functions used in the framework express. Although now I'm getting a sense that they simply just refer to functions that get in the middle between asynchronous functions.
I know it's common to see next() get used to move from one middleware to the next. Both express and mongoose have the next() call with similar names. I'm concerned as I don't see mongoose or express refer to each other in their documentation. So this leaves me to believe the context of their middleware is just for themselves.
http://mongoosejs.com/docs/middleware.html
http://expressjs.com/en/resources/middleware.html
When combining express with mongoose are all the middlewares lined up together/concatenated or is it separate?
e.g. together/concatenated
- calling next() on mongoose will also trigger expresses middleware function
e.g. Separate
- mongoose just has it's middleware next() just move for pre/post hooks
- express also just has it's middleware next() just move towards it's supported middleware functions
Short answer: they're separate.
Longer answer: By convention, most middleware stacks implement some kind of next function to call in order to proceed down the stack and call each middleware function in turn.
It's a matter of scope. Express and Mongoose both have their own independent middleware stacks, so what the next function does depends on where it gets called. As a general rule of thumb, every function-- including the anonymous functions used for callbacks that accept a next parameter-- have their own scope.
Consider the following really brief example of differently scoped, but otherwise identical parameter names:
function doSomething(arg) {
console.log(arg)
function doSomethingElse(arg) {
console.log(arg);
}
doSomethingElse('different');
}
doSomething('original');
// Outputs
// > 'original'
// > 'different
Even though doSomething and doSomethingElse both have a parameter called arg, the value logged to the console by doSomethingElse is the value actually passed to that function-- the value of arg as scoped to the function it was called in, not the scope surrounding it.
This is true for Mongoose middleware applied within Express middleware (or vice-versa): they just happen to share a similar, conventional parameter name.
As a learning experiment, you should deviate from conventions for a moment (but not forever; conventions exist for a reason!) to name your Express and your Mongoose next parameters something else in a single file-- expressNext and mongooseNext, perhaps-- to help differentiate them in your mind.
I would like to add method such as view and json to the context object passed to my controllers. I do this in a middleware that runs before everything else:
async function(ctx, next){
ctx.view = view.bind(ctx);
ctx.json = json.bind(ctx);
await next()
ctx.renderer.render();
}
these methods set some conventional configuration object (Renderer) that the middleware interprets and then renders out the actual response by setting the correct ctx.body. That allows me to switch template language easily and have an easier time combining API and Template requests.
Except it doesn't work because after await next() the ctx.renderer is the default one, not the one set by controllers. I suspect it's a namespacing issue, but I am not sure where it comes from.
What's the best practice to attach functions to the context that can reference context without it being passed to them?
Ok it's here in the docs I just missed it, the docs are inside a repo and are not hosted, which makes them hard to navigate.
TL;DR: use app.context to access the context prototype. Adding functions there attaches them to the context object and allows you to use this from within to access it.
If I have multiple urls like '/some/url/path/foo/bar1', '/some/url/path/foo/bar2', '/some/url/path/foo/bar3' etc. How can I write a single route that will direct the urls to the foo controller and the action of bar1, bar2, bar3 etc.
EG. (only this doesn't work.)
'/some/url/path/foo/:bar' : 'foo.:bar'
There are different ways to do this. I might suggest that you don't need the different actions in your controller, but just have different cases in a single action that respond to a url param (ex bar). That would be more inline with conventions.
However, you can accomplish what you want with the following.
Create your route
'/some/url/path/foo/:action': {
controller: 'FooController',
action: 'getAction'
}
Then in that controller create a getAction method. This method can now use req.param.action variable to find an execute the corresponding action.
FooController.getAction = function(req,res,next){
return sails.controllers.foo[req.param.action](req,res,next)
}