JSON API result format - json

Folks,
Designing my first API in Node.JS using restify.js. My background is not webapis, pardon my amateur questions. In any case, I would like to have the res.send(data); responses to comply with the http://jsonapi.org/format/ so that my mobile application can start utilizing the api calls. At the moment if you were to call my api, it would return data in the following format:
{"Count":1,"Items":[{"dbsource":{"S":"foo"},"id":{"S":"5002820"},"name":{"S":"fnameblah,lnameblah"},"expiration":{"S":"06/13/2015"},"type":{"S":"bar"}}]}
Actually what you see above is just a return of a DynamoDB Query call.
So the question is... do you use a special library that you can pass data to, which would format and return the data in JSON format. Which in turn you can return it via res.send(data) to the clients, or is it up to us to make 'data' JSON compliant, then return it? At the end of the day we all want the results to look like:
{
"posts": [{
"id": "1",
"title": "Rails is Omakase",
"links": {
"author": "9",
"comments": [ "5", "12", "17", "20" ]
}
}]
}
Thanks!

In server side, stringify JSON object,
//...
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify(data)); //data is JSON object
res.end();
In client side, parse JSON string accordingly.
EDIT: Corrected response content type.

JSON data from server should be a JSON string
You have to parse it back the JSON format in client.
JSON.parse(string); // return JSON object

Related

AWS API Gateway VTL Include Source API JSON in Response Template

We would like to include the Integration/Source API JSON in the response, but when we attempt to include the Object, it does not encode properly.
"success": true,
"message": "Resource Call Made Successfully",
"data": {ip=127.0.0.1, ipv4=127.0.0.1, ipv6=0:0:0:0:0:0:0:0, asn=null, asn_name=null, country=US, useragent={family=Other...
As you can see, the strings lose their quotes; breaking the JSON. Here's the template;
#set($inputRoot = $input.path("$"))
{
"success": true,
"message": "Resource Call Made Successfully",
"data": $inputRoot
}
I've tried using $json.parse(), escaping, etc with no luck. Anyone familiar enough to give some direction on how to stringify this so I can include it in the response?
Use syntax like below,
"subject": "$util.escapeJavaScript($input.path('$.Attributes.subject.S')).replaceAll(\"\\\\'\",\"'\")"
It's an explanation in $util.escapeJavaScript() function

422 error trying to save json data to the database

I'm trying to save data to my MySql db from a Node method. This includes a field called attachments.
console.log(JSON.stringify(post.acf.attachments[0])); returns:
{
"ID": 4776,
"id": 4776,
"title": "bla",
"filename": "bla.pdf",
"filesize": 1242207,
"url": "https://example.com/wp-content/uploads/bla.pdf",
"link": "https://example.com/bla/",
"alt": "",
"author": "1",
"description": "",
"caption": "",
"name": "bla",
"status": "inherit",
"uploaded_to": 0,
"date": "2020-10-23 18:05:13",
"modified": "2020-10-23 18:05:13",
"menu_order": 0,
"mime_type": "application/pdf",
"type": "application",
"subtype": "pdf",
"icon": "https://example.com/wp-includes/images/media/document.png"
}
This is indeed the data I want to save to the db:
await existing_post.save({
...
attachments: post.acf.attachments[0],
)};
However, the attachments field produces a 422 server error (if I comment out this field, the other fields save without a problem to the db). I'm not getting what is causing this error. Any ideas?
I've also tried
await existing_post.save({
...
attachments: post.acf.attachments,
)};
but then it seems to just save "[object Object]" to the database.
The field in the database is defined as text. I've also tried it by defining the field as json, but that made no difference.
exports.up = function (knex, Promise) {
return knex.schema.table("posts", function (table) {
table.longtext("attachments");
});
};
The 422 error code is about the server unable to process the data you are sending to it. In your case, your table field is longtext when post.acf.attachments seems like an object. That's why it saves [object Object] to your db (It is the return value of the toString() method).
Try using
await existing_post.save({
...
attachments: JSON.stringify(post.acf.attachments),
)};
MySQL and knex both support the JSON format, I'd suggest you change the field to json. (See knex docs and mysql 8 docs). You'll stiil need to stringify your objects tho.
EDIT: I just saw that Knex supports jsonInsert (and plenty other neat stuff) as a query builder that should be useful for you.
Mysql also support a large range of cool stuffs for handling jsons
In addition, when you fetch the results in the database, you'll need to parse the JSON result to get an actual JSON object:
const acf = await knex('posts').select('acf').first();
const attachment = JSON.parse(acf.attachment;
Knex also provide jsonExtract that should fill your needs (See also the mysql json_extract

Extract all the JSON data using Kotlin Android Studio

I'm using Volley library to communicate with my API. I'm pretty new to Android and Kotlin and I'm really confused about extracting keys from the following JSON data
{
"message": {
"_id": "60bc7fa7abeedb25643fa692",
"hash": "3a54b415461a63abac1fc6dfa0e140584047bd15358e33a177f9505ed2faa4d4",
"blockchain": "ethereum",
"amount": 5000,
"amount_usd": 13352971,
"from": "d3d69228cb2292f933572399593617f574c70eb1",
"to": "fe9996da73d6bf5252f15024811954ae37ab68be",
"__v": 0
}
}
The volley library returns all of this JSON data in a variable called response and I'm using response.getString("message") to extract the message key but, I don't understand how to extract the internal data such as hash, blockchain, amount, etc.
I'm using the following code to get the JSON data from my backend.
val jsonRequest = JsonObjectRequest(
Request.Method.GET, url, null,
{ response ->
tweet_text.setText(response.getString("message"))
Log.d("resp", response.toString())
},
{
Log.d("err", it.localizedMessage)
})
Any help would be appreciated, Thanks!
I found it, I just used the getJSONObject() method to make it work
val jsonRequest = JsonObjectRequest(
Request.Method.GET, url, null,
{ response ->
val txn = response.getJSONObject("message")
//txn object can be used to extract the internal data
},
{
Log.d("err", it.localizedMessage)
})

Zapier Catch (Raw) Hook JSON parsing issue

I would like to configure sync between two different CRMs (Clevertap and Intercom) using Zapier and Webhooks. In general Clevertap sends the following JSON to webhook:
{
"targetId": 1548328164,
"profiles": [
{
"event_properties": {
"MSG-sms": true,
"MSG-push": true,
"businessRole": "EMPLOYEE",
"Mobile Number": "123123123123",
"Name": "Artem Hovtvianisa",
"Title": "Mr",
"Last Name": "Hovtvianisa",
"Gender": "M",
"Customer type": "Business Account Holder",
"MSG-email": true,
"First Name": "Artem",
"Last seen IP": "111.177.74.50",
"tz": "GMT+0200",
"International customer": "yes",
"isBusiness": true,
"Email": "xxxyyy#gmail.com",
"Identity": 15675
},
"objectId": "e32e4de3c1e84b2d9bab3707c92cd092",
"all_identities": [
"15675",
"xxxyyy#gmail.com"
],
"email": "xxxyyy#gmail.com",
"identity": "15675"
}
]
}
Zapier provides two types of catch webhook: regular and Raw.
Catch Raw Hook
When I use this type, JSON raw data will be handled OK and on the next step (Zapier JS code app) I am able to pass proper JSON data like in example above.
However when I use simple JS code to parse JSON object and get profiles[0] array value I get the following error "TypeError: Cannot read property '0' of undefined"
JS Code from Code step:
var result = JSON.parse(JSON.stringify(inputData));
console.log(result.profiles[0]);
return result;
Catch Hook
In case I use regular Catch Hook, hook parse data in some odd way, like this:
JSON.parse cannot recognize this structure.
Please advise how can I handle Webhook Zapier step in a proper way in order to get profiles[0] array item values?
Thanks in advance!
David here, from the Zapier Platform team. You're on the right track!
Catch Raw Hook is the way to go here. Your issue is that the data is coming in as a string and you're re-stringifying it before parsing it, which gets you back to where you came from. A simpler version:
JSON.stringify("asdf") // => "\"asdf\"", quotes in the string
JSON.parse("\"asdf\"") // => "asdf", the original string
"asdf".profiles // => undefined
undefined[0] // => error, cannot read property "0" of undefined
Instead, just parse it and you're good to go!
// all your variables are already in "inputData", so yours,
// also named inputData, must be referenced explicitly.
const result = JSON.parse(inputData.inputData);
return {result: result, firstProfile: result.profiles[0]};

JSON string pulled via net/http to Hash

I'm trying to pull JSON from a Yahoo API to get the conversion rate of USD to SEK. However, I can't seem to get the JSON converted to a Hash, it shows "query" as being the only key since JSON comes in as one string.
The JSON request returns:
{"query":{"count":1,"created":"2016-12-04T13:06:00Z","lang":"en-us","results":{"rate":{"id":"USDSEK","Name":"USD/SEK","Rate":"9.1900","Date":"12/2/2016","Time":"9:59pm","Ask":"9.2000","Bid":"9.1900"}}}}
My code is as follow:
require 'net/http'
require 'json'
url = 'https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22USDSEK%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback='
uri = URI(url)
response = Net::HTTP.get(uri)
json_hash= JSON.parse(response)
puts json_hash["Rate"]
the puts statement returns 'nil'
I've tried following an example from this site, however I do not yield the same results based on the way my data is being brought as his is being statically entered.
*Note I am not using 'ostruct', trying simply with json.
Thank you for any insight.
As you can see, the field you are looking for is into an inner hash. Try
puts json_hash["query"]["results"]["rate"]["Rate"]
Have you check the structure of your json?
{
"query": {
"count": 1,
"created": "2016-12-04T13:06:00Z",
"lang": "en-us",
"results": {
"rate": {
"id": "USDSEK",
"Name": "USD/SEK",
"Rate": "9.1900",
"Date": "12/2/2016",
"Time": "9:59pm",
"Ask": "9.2000",
"Bid": "9.1900"
}
}
}
}
To fetch the rate key you should do something like:
json_hash["query"]["results"]["rate"]
Compare that with json above to understand your problem.