NodeJS HttpGet to a URL with JSON response - json

I'm trying to make a server-side API call using a RESTful protocol with a JSON response. I've read up on both the API documentation and this SO post.
The API that I'm trying to pull from tracks busses and returns data in a JSON output. I'm confused on how to make a HTTP GET request with all parameters and options in the actual URL. The API and it's response can even be accessed through a browser or using the 'curl' command. http://developer.cumtd.com/api/v2.2/json/GetStop?key=d99803c970a04223998cabd90a741633&stop_id=it
How do I write Node server-side code to make GET requests to a resource with options in the URL and interpret the JSON response?

request is now deprecated. It is recommended you use an alternative:
native HTTP/S, const https = require('https');
node-fetch
axios
got
superagent
Stats comparision
Some code examples
Original answer:
The request module makes this really easy. Install request into your package from npm, and then you can make a get request.
var request = require("request")
var url = "http://developer.cumtd.com/api/v2.2/json/GetStop?" +
"key=d99803c970a04223998cabd90a741633" +
"&stop_id=it"
request({
url: url,
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
console.log(body) // Print the json response
}
})
You can find documentation for request on npm: https://npmjs.org/package/request

Related

I can't resolve error with API POST function

I am trying to post data via an API interface.
I have checked the JSON of the data with JSON formatter and tested the API post in ReqBin and they work fine but when I execute it in App Script I get the same error, seemingly ignoring the attributes I put in the options variable.
Error is
{"code":"not_acceptable","message":"I can only talk JSON. Please set 'Accept' and 'Content-Type' to 'application/json' in your http request header."}
Note: I have tried sending just the data as the payload without json.stringify'ing it as it is formatted as JSON to start with.
In all cases it executes, but comes back 406
Is there another way to add 'Accept':"application/json" into the header??
My Code
function exportNation()
{
// Make a POST request with a JSON payload.
var data = {
"person":
{
"email":"mikenizzckelisaweiner#tv.com",
"last_name":"Bozzrovowski",
"first_name":"Edwzzard",
"tags":"Imported Data,Volunteer,Sign Request"
}
};
var options = {
"method":"POST",
"Content-Type":"application/json",
'Accept':"application/json",
'muteHttpExceptions':true,
'payload':JSON.stringify(data)
};
var response = UrlFetchApp.fetch('https://xyz.xyz.com/api/v1/people?
access_token=5604da84fXXXXXXXXXXXXXXXX42da1ea',options );
}
Any help would be greatly appreciated!
Additional HTTP headers need to be sent as a headers object.
See: https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app#advanced-parameters
var options = {
"method":"POST",
"contentType":"application/json",
"headers": {'Accept':"application/json"},

Why am I getting an empty response back from UrlFetchApp in Google Apps Script?

I am trying to make a GET request to an external API from a Google Apps Script using UrlFetchApp. When I make this request with Postman or curl, I get back the expected response. However, when I try it with UrlFetchApp, I get back an empty response, {}.
I have tried using Basic Auth and OAuth 2, as well as explicitly setting the oauthScopes property in the manifest as described here.
I have confirmed with the API team that they are indeed sending back a full response when I hit the endpoint, but all I receive is {}. My problem seems similar to this StackOverflow question which went unanswered.
var headers = {
"X-Client-Key": "KEY",
"Authorization": "Bearer TOKEN"
};
var options = {
method: "get",
headers: headers,
}
var response = UrlFetchApp.fetch(ENDPOINT, options);
console.log(JSON.stringify(response)); // returns {}
Do not take what you see in logs at face value. fetch method of the UrlFetchApp service always returns an instance of HTTPResponse which is an object first and foremost. This is what the logs show you (I am assuming you are logging the response because this is the only context I am aware of where {} is displayed).
To extract useful information from the response, use the appropriate methods exposed on HTTPResponse instances, like getResponseCode or getContentText.

Flask API can receive posts from AJAX but not Postman

We have a Flask API that talks to multiple sources, a web app, and an external source. In the web app, we use AJAX to send a JSON post to the API which is successful. From an external source, whether it's postman or the VaRest Unreal Engine plugin, we get a 400 Error: Bad Request even though we use the correct content-type header.
If anyone can help us figure out why the posts we are sending aren't properly identified we would really appreciate it.
Thanks
This is the JS code from our web app, used to create the JSON which is sent through AJAX (this is the successful code)
var but1 = document.getElementById('but1');
const data1 = {
number: 1 ,
type: 1 ,
value: 100
}
but1.addEventListener("click", function() {
$.post(url, data1);
});
This is a post route in our python API that takes in the input and saves it to a file we have
#app.route('/button', methods=['POST'])
def button():
buttonLog = open("buttonLog.txt", "w")
buttonLog.write(request.form['number'])
buttonLog.close()
typeOf = int(request.form['type'])
value = int(request.form['value'])
return "success"
Here is our JSON post, with headers
Postman JSON
Postman Headers
The AJAX post works as intended, but the postman post/Unreal engine post are not being seen as "posts" to the API.

Unable to access data inside a string (i.e. [ object Object ]) that was originally sent as a JSON object

I'm using axios to send a JSON object as a parameter to my api. Before it post request is fired, my data starts of as a JSON object. On the server side, when I console.log(req.params) the data is returned as such
[object Object]
When I used typeof, it returned a string. So then I went to use JSON.parse(). However, when I used that, it returned an error as such
SyntaxError: Unexpected token o in JSON at position 1
I looked for solutions, but nothing I tried seemed to work. Now I'm thinking I'm sending the data to the server incorrectly.
Here's my post request using axios:
createMedia: async function(mediaData) {
console.log("SAVING MEDIA OBJECT");
console.log(typeof mediaData)
let json = await axios.post(`http://localhost:3001/api/media/new/${mediaData}`)
return json;
}
Any thoughts on how I can solve this?
You need to update your code using axios to provide the mediaData in the body of the request instead of the URL:
createMedia: async function(mediaData) {
console.log("SAVING MEDIA OBJECT");
console.log(typeof mediaData)
let json = await axios.post(`http://localhost:3001/api/media/new/`, mediaData)
return json;
}
In the backend (assuming you're using express here), you need to configure your application to use bodyParser:
var express = require('express')
, app = express.createServer();
app.use(express.bodyParser());
And then in your controller update your console.log(req.params) to console.log(req.body); then restart your node server

Node / Express parsed JSON POST is not valid JSON

I am making a JSON POST request using Pure Javascript XMLHttpRequest, however Express appears to wrap the received JSON in an additional object, how can I prevent this ?
I am using the bodyParser:
app.use(bodyParser.json({limit: '50mb'}));
This is the client sending the JSON data:
var xhr = new XMLHttpRequest();
xhr.open("POST", "https://xxx.my.net/",true);
// This header MUST be present for POST requests.
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.setRequestHeader("Accept", "application/json, text/javascript");
xhr.send(JSON.stringify({"hxx":1}));
And this is Nodejs / Express middleware:
app.use(function(req, res, next){
fn.console.log(req.body);
})
This is the console.log output:
{ '{"hxx":1}': '' }
I know that I can parse the body with:
console.log(JSON.parse(Object.keys(req.body)[0]))
but I would prefer not to have to do this !
IMPORTANT Note
I have already tried using content type = "application/json" but when I do this the request becomes a GET instead of a POST, and Unless I state "application/x-www-form-urlencoded" the request is automatically converted by the browser from a POST to a GET.