writing node.js get handler with parameters? - node.js

How do I write a get handler for the following URL with node.js?
http://localhost:3000/auth?code=xxxxxxx
The following code did not work
app.get('/auth', function (req,res) {
});

It's not working because it doesn't do anything. You need to send a response:
app.get('/auth', function (req,res) {
res.send('Hi it worked. Code: ' + req.query.code);
});
Another way to do it would be like this:
app.get('/auth/:code', function (req,res) {
res.send('Hi it worked. Code: ' + req.params.code);
});
and the URL would simply be http://localhost:3000/auth/xxxxxxx

Please note that, some client sides should accept a certain response type.
For instance, you should send a JSON object as a response.
So, rather than just responding a string, it is better if you send a JSON object as:
app.get('/auth', function (req,res) {
res.send({ 'response' : 'Hi it worked.', 'code': req.query.code });
});

Related

endpoint don't work, doesn't return anything

¿can you help me to understand this?
If I have an endpoint in a specific route it will display in the browser the expected content, but with the same code just modifying the endpoint it doesn't return anything.
The only change that I do is the route of the endpoint, the rest of code is the same in both cases.
¿Why this happen?
The code displays in the browser the content of a json file:
this way it doesn't work:
It doesn't show an error, just don't return anything.
localhost:3000/v1/people/partner
app.get("/v1/people/partner", (req, res) => {
const peopleInVisual = PeopleController.getAllVisualPeople();
res.json({ peopleInVisual });
});
In this way it works fine: notice I just have changed the hello at the endpoint
localhost:3000/v1/hello/partner
app.get("/v1/hello/partner", (req, res) => {
const PeopleInVisual = PeopleController.getAllVisualPeople();
res.json({ PeopleInVisual });
});
Thanks!

Axios - send get request with url + variable

This must be a stupid question, but I'm just starting and would appreciate any help!
So I have this code to get query parameter:
app.get('/', (req, res) => {
var code = req.query.code;
console.log(code);
And when I go to http://localhost:3000/?code=123, I get the code value in console, so it works fine.
Now, I need to send a GET request and add the value of the var code, this is where I'm stuck.
Let's say, I should send a GET request to 'http://testtesttest123.com/' + var code + 'hi'.
How can I do this?
I've tried this way and some other ways, but nothing worked:
axios.get('http://testtesttest123.com/?&code=', {params: {code}}, '&hi')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
});
Thank you in advance!
The axios.get call should look like this.
axios.get('http://testtesttest123.com/?code=' + code + '&hi')
With code = 123, this will call the URL http://testtesttest123.com/?code=123&hi.
Use the params config to send through query parameters. To support your empty hi parameter, you can include it in the URL string
axios.get("http://testtesttest123.com/?hi", {
params: { code }
})
For a code value of 123, this will perform a GET request to
http://testtesttest123.com/?hi&code=123
It will also ensure that the code value is made safe for use in URLs

Transforming a payload from requestjs before sending it to the client

Brothers and sisters, I am building an Express API Endpoint that needs to consume an external API, perform some changing of keys and values, and return to the result to the client. Here is what I have thus far:
const external_endpoint = <external_api_end_point>;
app.get('/', function (req, res, next) {
request({ url: external_endpoint}).pipe(res);
});
This returns the exact payload you would get from hitting the external_endpoint directly.
Isn't there something I can do to change res before it gets sent to the client? I tried a few things but nothings has worked. Any ideas or best practices associated with doing a transform on the incoming payload?
For the sake of simplicity. Lets say this is the payload obj.json:
{
"sad": {
"userid": 5,
"username": "jsmith",
"isAdmin": true
}
}
and I am wanting to change sad to happy.
I know outside of the request I could do something like this:
obj = JSON.parse(JSON.stringify(obj).split('"sad":').join('"happy":'));
but throwing obj in place of res will not work. I have tried assigning the value of this res and res.body but no dice.
Thanks for you help in advance!
If you're using request-promise, you can simply make a new response and send it, or modify the response you got back:
app.get('/', function (req, res, next) {
request({ url: external_endpoint, json: true})
.then(response => res.json({ happy: response.sad })))
.catch(next);
});
(of course, you need to handle errors appropriately)
If you want to process it as a stream (which makes sense if you have a massive amount of data), you can use the original request module, and use event-stream to create your pipe:
const es = require('event-stream');
const swapper = es.through(
function write(data) {
this.emit("data", data.replace("sad", "happy"));
},
function end() {
this.emit("end");
}
);
request({ url: external_endpoint})
.pipe(es.stringify())
.pipe(swapper)
.pipe(es.parse())
.pipe(res);
Here's a sandbox to test the stream processing: https://codesandbox.io/s/3wqx67pq6

express DELETE route acting strange? Unexpected token 'n'

the delete route:
router.delete('/users/:name' , function (req, res, next) {
User.deleteOne({name: req.params.name}).then (function (user) {
console.log('DELETED / ', req.params.name);
res.send('DELETED / ', req.params.name);
}).catch (next)
});
the router.get and router.post under the same '/users/' work no problem.
I get a strange error when I try this,
{
"error": "Unexpected token n in JSON at position 3"
}
although I have a 200 OK status response. Any idea what is going on? I'm trying in postman.
UPDATE:
Lesson learned here. Make sure your testing methods are in fact correct.
I was sending a different header that somehow got mixed up in postman which causes errors. It was a hard to notice at first but clicking the setting I discovered there as a strange extra huge JSON batch being sent back. Even though at first glance everything seemed ok
Try like this :
router.delete('/users/:name' , function (req, res) {
User.deleteOne({name: req.params.name})
.exec()
.catch (err => res.status(500).send(err) )
.then (function () {
console.log('DELETED / ', req.params.name);
res.send('DELETED / ', req.params.name);
})
});
Based on the Express API reference of res.send():
When the parameter is an Array or Object, Express responds with the JSON representation
Your code above seems to send the string "DELETED / " back. Maybe that is the reason why your JS code raise JSON parse error.
Try replace res.send statement with this one below:
res.send({msg : 'DELETED / ', user: req.params.name});
Hope this helps.

Express logging with storing the request information

Background
Yes, there are a lot of different Node.js logging library winston, bunyan and console.log. It's easy to log down the information of the specific request when it has called and when and what information would be in response.
The problem
The problem begins with the sub function calls. When under one request your calling multiple functions which also uses the same logging, how would you pass the request meta - data to these log calls (function parameters seems to be one possible way but these are really messy) ?
Example
Small visual for coders:
// Middleware to set some request based information
app.use(function (req, res, next) {
req.rid = 'Random generated request id for tracking sub queries';
});
app.get('/', function (req, rest) {
async.series({
'users': async.apply(db.users.find),
'posts': async.apply(db.posts.find),
}, function (err, dbRes) {
console.log('API call made ', req.rid)
res.end(dbRes);
});
});
// Now the database functions are in other file but we also need to track down the request id in there
(db.js)
module.exports = {
users: {
find: function () {
console.log('Calling users listing ', req.rid); // ERROR this is not possible to access, not in this scope
// Make query and return result
}
},
posts: {
find: function () {
console.log('Calling post listing ', req.rid); // ERROR this is not possible to access, not in this scope
// Make query and return result
}
}
};
You can log your requests with simple conf in your app.js with;
app.use(function(req, res, next){
console.log('%s %s', req.method, req.url);
next();
});
However, you need to provide logs for specific functions in your controller.

Resources