How does JSON data get sent in an http request? - json

Let's say I'm making the http request below, to update some record in a mongoDB database:
PUT
http://dev.mycompany.co/ping
{"id":4432, "name":"Jane Doe", "products":[ {"id":287}, {"id":434} ] }
Notice that there is an array of two objects inside the "products" property of the JSON above. I have data that is being sent in this general format, both through Fiddler and through a ruby script I've written.
When sent through Fiddler, my data in the JSON is correctly parsed and updated into my database. When sent through my ruby script, the data in the JSON is not parsed correctly. I've been trying to figure out why this is. Now, I'm wondering how data is actually sent when a JSON is sent along with an http request. Can someone point me in the right direction?

After asking a few other questions on SO and doing a bunch more research, I've arrived at the following conclusions.
Q: How does JSON data get sent in an http request?
A: It depends on how you are sending the JSON data in the request (what is the content-type)
I've encountered two ways that JSON data is sent.
Sent using content-type application/json
With this content-type, JSON data is sent literally as-is. The literal JSON data is stored as a string and sent with the request. If your JSON is complex, with nested objects and arrays and such, this is probably what you want. For a working example of sending nested JSONs using Ruby's Net/HTTP, see the answer on this SO question I asked.
Sent using content-type x-www-form-urlencoded
This is how Ruby's Net/HTTP requests typically get sent out. The form of these requests is something like: id=343?entity=Microsoft?foo=bar. This content-type is fine until you have a complex JSON.

Related

Map entire Webhook Response in Marketo Webhook

I have a web-hook that calls an API that returns a single plain text response. The response isn't formatted in JSON or xml because the response is a single piece of data, not a map or array. I see plenty of examples of how to extract a field from a JSON response and store it in a marketo token but no example of how to store the whole response payload. Here is a sample response from the API:
alsdfjasdhfalksdhfalksdjalksdk
Note that the response is not anything like this:
{
"field":"alsdfjasdhfalksdhfalksdjalksdk"
}
Maybe some Marketo expert has done this and could share. I'd appreciate it, thanks.
Marketo's parsing of XML and JSON is limited, to say the least--so your webhook does need to declare some sort of key-value pair so the response can be mapped. Given what you're describing, you could likely just hardcode in the surrounding JSON with the right MIME type and be fine.
Basically, Marketo can only handle the following for JSON webhook responses:
Key-value pair
Key can only be defined by placement (no XPath or similar--you'd be stuck with field[1] or similar)
Ideally no nesting, as Marketo doesn't do a great job of reading nested data--largely for the reason mentioned above

Node.js express res.json behavior

I have been working on one of my projects using node and ng4
when I came across using res.json to send an array back to Angular 4 front end, like res.json(arrayResult). Surprisingly, I cannot use JSON.parse(arrayResult) after Angular receives it because it throws an error saying unexpected end of input. I however can access all the data through result[i], just like any normal array.
I don't quite understand why res.json() does not send my array as a string to the front end. Is there any internal conversion involved? Why I could access the content through index without even parsing it or doing any conversion with it?
The server indeed send your json data as a string. Additionally to the string, the server passes Content-Type header to your client which tells your client what kind of data you received.
So if the Content-Type was text/html your client would think that he received an HTML file.
In your case, res.json using Content-Type: application/json which tells the client that the string that he got is actually a json object, so no need for you to use JSON.parse.
You can see the Content-Type under the response headers property.

Sample JSON request for multipart form

I want to call a rest API and my request body is composed in a json file. I want to send the request as multipart/form. Request body containst some text fields and several files for which I decide to use multipart form. I have found alot of logical example requests on internet but no concrete example in json format.
How would a sample json request body look like?
Finally found out that there is no such JSON representation of multipart/data requests. Infect thats just not possible using the json format. So multipart data request literally looks like the attached screenshot:

Should webhook JSON payloads be URL encoded?

New Relic currently URL encodes the JSON payload of our webhooks. We correctly include the necessary header, however, I'm wondering if this is best practice - or if the JSON payload should be sent un-encoded (or even with some different encoding)?
It's more common to send JSON directly in the request body with a Content-Type header value of application/json. It's not entirely uncommon to do it the way New Relic does however. GitHub post-receive hook payloads are also encoded this way.
In some languages/frameworks it's easier to extract the JSON data from a parameter than from reading the entire request body since form parameters are automatically parsed out and easily referenced and in some cases reading a request body may involve some more elaborate stream parsing.
An example of that is PHP's syntax for extracting the entire raw request body:
$data = file_get_contents('php://input');
var_dump(json_decode($data));
Versus extracting from a form parameter:
$data = $_POST["payload"];
var_dump(json_decode($data));
For frameworks that easily expose the request body, this isn't as much an issue. Here's the example given from the GitHub docs for handling the hook with Sinatra:
post '/' do
push = JSON.parse(params[:payload])
"I got some JSON: #{push.inspect}"
end
If the JSON body were passed directly, this is what it would look like:
post '/' do
push = JSON.parse(request.body.read)
"I got some JSON: #{push.inspect}"
end
It's mostly just an aesthetic preference, there's no technical advantage to either. With the parameter, you do get the flexibility of sending multiple JSON payloads in a single request or the option to send additional meta data outside the JSON. I would suggest sending a list of JSON objects and including all the meta data in a top level wrapper if that's important to you. Something like this:
{
"notification_id": "akjfd8",
"events": [ ... ]
}
I personally prefer raw JSON bodies, but that's mostly because it makes debugging far easier on sites like RequestBin. Your screenshot does a great job of illustrating how unreadable JSON encoded into a form parameter is.
<rant>
Payloads should be the content type you say they are. If they are sending as application/x-www-form-urlencoded then that is what you should expect to find. The culture of using a Russian doll model of nested encodings is beyond stupid in my opinion.
If you want to send JSON send it as application/json. Is that really so hard?
</rant>

How does server handle JSON in the body of a POST

I am using jQuery to post JSON data to a tomcat server and the server is handling the JSON array data perfectly! It is as though I passed key=value request parameters along with the URL.
So why am I posting this? I would like to know how the server treats JSON in the body of a request and how the data ends up being interpreted as request parameters. I have Googled my a** off and all I find is how the server sends JSON back to the client.
$.ajax() converts JSON data into key-value pairs (querystring style) by default. You need to set { processData : false } in the AJAX request to keep it as raw JSON.