Making REST call from Node.js and sending response to browser - node.js

I am beginner to Node.js, so as per project requirements I am trying to call REST service from Node.js, I got information of how to call rest from this SO question. Here is the code to make rest call:
var options = {
host: url,
port: 80,
path: '/resource?id=foo&bar=baz',
method: 'POST'
};
http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk); //I want to send this 'chunk' as a response to browser
});
}).end();
The problem is I want to send chunk as a response to a browser, I tried res.write() but it is throwing me error "write method not found". I looked in docs everywhere, but all they give is console.log. Can anyone let me know how can I send that data as a response to a browser?

The callback to http.request is an instance of IncomingMessage, which is a Readable Stream that doesn't have a write method. When making an HTTP request with http.request, you cannot send a response. HTTP is a request-response-message-oriented protocol.
how can I send that data as a response to a browser?
For a browser to be able to get response, it must make a request first. You'll have to have a server running which calls the REST service when it receives a request.
http.createServer(function(req, res) {
var data = getDataFromREST(function(data) {
res.write(data);
res.end();
});
});

Related

Nodejs - parse response data without parsing as String?

I'm following some tutorials online, and I'm trying to parse a response from an HTTP post call from my node app. My app acts as an interceptor, we make a POST request to the interceptor app, I transform the data, then I post it to another client to perform some action, and then I want to return the response from the other app as my app's response. Below is the code I use to make the post:
const request = http.request(options, function(response) {
console.log('STATUS: ' + response.statusCode);
console.log('HEADERS: ' + JSON.stringify(response.headers));
response.setEncoding('utf8');
response.on('data', function (chunk) {
console.log('BODY: ' + chunk);
//res is the actual response object to my app's own post function
res.status(response.statusCode).send({response:chunk});
});
});
Now, the response to the post object looks like ["Hey there! How can I help you?"].
However, when I return that as a response to my API, the body looks like:
"response": "[\"I am doing well. Thank you for asking.\"]\n".
I want to interact with the array that is returned, grab the string at index 0, and return that as my response. Is this possible?
Have you tried?
res.setHeader('content-type','application/json');
res.status(response.statusCode).send(chunk);

DELETE request to REST API returns 500

function delete(id, response) {
var https = require('https');
var linkpath = "/v1/endpoint/" + id + "/?token=" + AUTH_KEY;
var req = https.request({
hostname: 'api.foo.com',
port: 443,
path: linkpath,
agent: false,
method: 'DELETE',
}, (res) => {
if (res.statusCode !== 200) {
response.send('HTTP ' + res.statusCode + ' ' + res.statusMessage);
}
res.on('error', function (err) {
response.send(err);
});
res.on('end', function (data) {
response.send(data);
});
});
req.on('error', function(e) {
response.send(e.message);
});
req.end();
}
This code, adapted from my (working) code that uses a POST request to do other things with this API, nets me a status code of 500 from the endpoint.
I don't know how to debug this. I can't send the URL manually to the server because it's a DELETE operation instead of a GET or POST.
Has anyone seen this problem? Or do you have ideas on how to debug it?
Postman (https://www.getpostman.com/) is a great tool for manually sending specific HTTP requests, including DELETE!
There are all sorts of tools that will let you manually send any HTTP to the server. For instance, you can get quite a bit of information with curl, which will happily send a DELETE request.
For example:
curl -v -X "DELETE" https://jsonplaceholder.typicode.com/posts/1
will return the request and response headers as well as the body of the return value if any.

How to return NodeJS HTTP Request errors without waiting for timeout?

I have an application based on NodeJS/Express and AngularJS which talks to a, application server via REST API. In the event that the application server is not running, I would like to immediately return an error to the AngularJS client that the calls are failing.
Here is what I currently have:
var jsonObject = JSON.stringify(input);
var postHeaders = {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(jsonObject, 'utf8')
};
var options = {
host: '127.0.0.1',
port: 7777,
path: path,
method: method,
headers: postHeaders
};
var appServerRequest = http.request(options, function(appServerResult) {
console.log('STATUS: ' + appServerResult.statusCode);
console.log('HEADERS: ' + JSON.stringify(appServerResult.headers));
appServerResult.setEncoding('utf8');
var responseDataString = '';
appServerResult.on('data', function(chunk) {
responseDataString += chunk;
console.log('BODY: ' + chunk);
});
appServerResult.on('end', function() {
callback(responseDataString);
});
appServerResult.on('error', function(e) {
console.log('** Result ERROR in appServerResponse');
console.log(e);
});
});
appServerRequest.on('response', function(response) {
console.log('Response: ' + response);
});
appServerRequest.on('error', function(e) {
console.log('** Request ERROR in appServerRequest');
console.log(e);
});
appServerRequest.write(jsonObject);
appServerRequest.end();
As you can see, I'm listening to the 'error' events on both the Request and Response objects. When a call is made and the application server is not running, the Request error handler is called as expected. However, I haven't been able to figure out how to take that error and return it to the client. A response object is eventually returned, but only after the timeout expires. It seems like there should be a way to return a Response and specify an appropriate HTTP Status code as soon as I detect the error. I could do it if I had a response object (of course), but I don't get one until the timeout expires.
I know I must be missing something simple, but I can't figure out what it is.
You mention you're using express. Simply call res.send(500) to end the request with an error code (in this case 500)

408 Timeout in NodeJS app requesting Github API

Following the documentation of the Github API to create an authorization for a NodeJS app.
I have the following code:
var _options = {
headers: {
'User-Agent': app.get('ORGANISATION')
},
hostname: 'api.github.com'
};
var oauth2Authorize = function () {
var path = '/authorizations?scopes=repo';
path += '&client_id='+ app.get('GITHUB_CLIENT_ID');
path += '&client_secret='+ app.get('GITHUB_CLIENT_SECRET');
path += '&note=ReviewerAssistant';
_options.path = path;
_options.method = 'POST';
var request = https.request(_options, function (response) {
var data = "";
response.on('data', function (chunk) {
data += chunk;
});
response.on('end', function () {
console.log(data);
});
});
request.on('error', function (error) {
console.log('Problem with request: '+ error);
});
};
And all I get is:
408 Request Time-out
Your browser didn't send a complete request in time.
Doing a GET request works though.
http.request() doesn't immediately send the request:
With http.request() one must always call req.end() to signify that you're done with the request - even if there is no data being written to the request body.
It opens the underlying connection to the server, but leaves the request incomplete so that a body/message can be sent with it:
var request = http.request({ method: 'POST', ... });
request.write('data\n');
request.write('data\n');
request.end();
And, regardless of whether there's anything to write() or not, you must call end() to complete the request and send it in its entirety. Without that, the server will eventually force the open connection to close. In this case, with a 408 response.

Using http.request in Node.JS while passing an API key

I am currently fiddling around with Node.JS to try to create a package for PostageApp to be able to send emails through our API.
To start, I am using the following code to test out how Node.JS can best interface with our API, but it doesn't seem to want to pass along the API key that I have attached as part of the headers.
var http = require('http');
function onRequest(request, response) {
response.end();
}
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
var options = {
host: 'api.postageapp.com',
path: '/v.1.0/get_account_info.json',
method: 'POST',
headers: { "api_key" : "MY API KEY HERE" }
};
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.end();
console.log("Request sent!");
I pulled this together using various examples and what not - it's not pretty, I know. However, using HTTPS, I finally got it to hit our API and get a response:
{"response":{"status":"unauthorized","message":"Invalid or inactive API key used","uid":null}}
The only conclusion I can come up with is that the API key is not getting passed along, and I would appreciate any help as to how to make that happen.
Thanks!
Here's an example of code I have used to call web APIs with a key in the header:
var api = http.createClient(80, 'api.example.org');
var request = api.request('GET', '/api/foo',
{
'host': 'api.example.org',
'accept': 'application/json',
'api-key': 'apikeygoeshere'
});
request.on('response', function (response) {});
request.end();

Resources