Express route with /? - node.js

I want to route 2 different requests.
/api/heroes/:id
/api/heroes/?name=
So using nodejs and express I write the server to handle this request.
To handle the first request I write below code:
app.get('/api/heroes/:id', jsonParser, function (req, res) {
To handle the second request I write as below:
app.get('/api/heroes/name', jsonParser, function (req, res) {
But only the first handle working as expected. The 2nd request is handled by:
app.get('/api/heroes', jsonParser, function (req, res) {
How do I change the code so the second handle can work?

If I correctly got your question, then probably you asking why req for /api/heroes/?name= is handled by /api/heroes.
You are trying to send query string parameter in 2nd req which will be handled by route /api/heroes. You will get query string parameter in req.query object.
So, your first request handler will work for urls - /api/heroes/:id (eg - /api/heroes/123) as follow:
app.get('/api/heroes/:id', function (req, res) {
var id = req.param.id
}
and for 2nd req: /api/heroes?name= (eg - /api/heroes?name=abc)
app.get('/api/heroes', function (req, res) {
var name = req.query.name
}
Refer here req.query

This is what is expected:
For query parameters /api/heroes/?name= is handled by
app.get('/api/heroes', jsonParser, function (req, res) {
What you can do is to check if req.query.name is undefined then act as normal or act with the query. Using if...else condition.
/api/heroes/name is the endpoint with name.
You can differentiate if you want as below:
app.get('/api/heroes/name/:text', jsonParser, function (req, res) {

Related

nodejs get req.param from route

I am trying to get the url parameter of an url request from the front in my nodejs backend.
fetch(`http://localhost:9000/sent/5768797675645657`)
Here is my app.js file :
app.use('/sent/:id', require('./routes/sent'));
And my /routes/sent.js file :
router.get('/', function(req, res) {
console.log(req.params)
})
How can I get the console.log(req.params) to work?
So, app.use accepts two parameters: the portion of the URL, and a callback function.
In order to your app works, you've to change the /routes/sent.js and make it exports the function, so it can be used when you're requiring it.
Just change it to
module.exports = function (req, res) {
console.log(req.params)
}
and you're ready to go!

first portion of route url is not included

I have a route where I built two GET APIs. I would like one to redirect from /download to /zip all while passing a parameter. The problem is I am getting a 404 for some reason the routes url is not being included in the redirect()
Here are the APIs.
// respond with xml from from static folder
router.get('/zip/:id', function (req, res) {
fileName = req.params.id
});
router.get('/download', function (req, res, next) {
var id = req.query.id
res.redirect('/zip?id='+ id);
});
module.exports = router;
I get a 404 when testing the URL:
localhost:8000/rest/pluto/v1/plugin/download?id=networktool
I am thinking it might be how I have the middleware setup but not real sure. I'm still new to node/express.
You are redirecting to a route that isn't actually defined. With your /zip/:id route definition:
router.get('/zip/:id', function (req, res) {
var fileName = req.params.id
});
The way that is defined, you have to have id information in the URL itself, so while the following routes would work:
/zip/networktool
/zip/1234
these routes would not:
/zip
/zip?id=networktool
/zip?id=1234
because Express is looking for the id to be built into the route itself. So you can do one of two things. You can either change your redirect to:
router.get('/download', function (req, res, next) {
res.redirect('/zip/'+ req.query.id);
});
or, you can modify your /zip route to make the id parameter optional with ?:
router.get('/zip/:id?', function (req, res) {
var fileName = (req.params.id) ? req.params.id : req.query.id;
});
I would recommend the first option, as the latter optional parameter only makes your zip route more complicated and require extra handling of whether id is actually passed to your route.
The path /zip/:id is expecting a path parameter not a query parameter.
You should redirect like this
res.redirect('/zip/'+ id);

How to change ?url= into a node structured route

So I am currently doing the following.
http://example.com/podcast?url=https://storage.googleapis.com/radiomediapodcast/QWA/S01/QWAS1E1.mp3
However, I want to do the following.
http://example.com/podcast/https://storage.googleapis.com/XXX/XXX/S01/QWAS1E1.mp3
I understand that router.get('/:url', (req, res) => {
should allow me to send http://example.com/podcast/http
I also understand that
router.get('/:url*', (req, res) => {
should also allow http://example.com/podcast/https://storage.googleapis.com/XXX/XXX/S01/QWAS1E1.mp3`
The * enables the route to be called for your url and the req.params would let you read the the inner url passed along with.
Try the following route with http://example.com/podcast/https://storage.googleapis.com/XXX/XXX/S01/QWAS1E1.mp3
router.get('/prodcast/*', async (req, res, next) => {
console.log(req.query.params); //https://storage.googleapis.com/XXX/XXX/S01/QWAS1E1.mp3
res.status(200).send('ok');
});
Define you router like
app.get('/podcast/:url(*)', (req, res) =>
:url(*) instead of :url*
Now you can get your url via req.params.url.
You can use your way (:url*), but you need some trick to get your url data, in this case, req.params will be like
{
0: "//example.com/podcast/https://storage.googleapis.com/XXX/XXX/S01/QWAS1E1.mp3",
url: "http:"
}
Then, the url data will be: const url = req.params.url + req.params[0];

How return statement work in nodes

I am newbie in ExpressJs and I do not clear about return statement of middleware. Please see below code :-
middleware.js
exports.checkPrivilege = (stateName, forPrivilege) => {
return (req, res, next) => { // THIS LINE MAKE CONFUSE, i.e, req, res and next
}
}
module.js
.....
.....
router.post('/create', checkPrivilege('module', 'write'), (req, res, next) => {
});
This means that checkPrivilege() is a function that, when called returns another function. In this case, it returns a function that is of the right format to use as a middleware handler.
So, when checkPrivilege(x,y) is called, it returns another function (that has not been executed yet) that can then be used as middleware.
So, when you see this:
router.post('/create', checkPrivilege('module', 'write'), (req, res, next) => {
// code here
next();
});
This does the following steps:
Creates a POST route handler for the /create route.
Calls checkPrivilege('module', 'write') immediately and as the return value it gets back another function that becomes a middleware handler for the /create route.
Then defines an inline anonymous route handler function for the /create route that will run after the middleware handler is done.
For a bit of clarity, it could also be written:
// create middleware function
let checkPrivilegeMiddleware1 = checkPrivilege('module', 'write');
// create route handler with middleware
router.post('/create', checkPrivilegeMiddleware1, (req, res, next) => {
// code here
next();
});
The typical reason it's done this way is that it is an easy way to make some parameters stateName and forPrivilege available to the middleware without creating another inline function body. This way the checkPrivilege() function can be used in multiple places within your code, each with their own stateName and forPrivilege settings - thus more reusable.

I would like to add a query param apikey for all my external call

I have a server in express and it uses an external api. I would like for each request to that api ('/api/*'), that it appends a query param in the url without to write it for each requests.
app.use(function(req, res) {
req.query.key = process.env.APIKEY;
});
I tried something like that but it doesn't work.
I thought of doing something like :
app.get('/api/stuff', addApiKey, api.stuff);
Is there a better way?
You need to supply your middleware function with a next callback:
function addApiKey(req, res, next) {
req.query.key = process.env.APIKEY;
next();
});
app.get('/api/:endpoint', addApiKey, function(req, res) {
// do your stuff here
});

Resources