Emitting JSON with optional arguments (Google API) - json

I'm writing a JSON emitter for a Google API. The API documentation says that some fields are "optional". How am I supposed to interpret that? I've looked at json.org's language specification and it doesn't say. Google's docs are not clear on the subject either.
For example, consider the "sellerData" field in the following:
{
"iss" : "1337133713371337",
"aud" : "Google"
"typ" : "google/payments/inapp/item/v1",
"exp" : "1309988959",
"iat" : "1409988959",
"request" :{
"name" : "Piece of Cake",
"description" : "Virtual chocolate cake to fill your virtual tummy",
"price" : "10.50",
"currencyCode" : "USD",
"sellerData" : "user_id:1224245,offer_code:3098576987,affiliate:aksdfbovu9j"
}
}
If I didn't have any "sellerData" to send, should I just send "sellerData": Null or just not put the field in at all? The former would make my emitter code much cleaner.

Optional fields can be completely omitted.
If you do not need "sellerData", do not add it to the JSON.
Once you set up a merchant sandbox account, the online documentation has a JWT generation tool that let's you experiment with setting various field values.
You can also double check your JWT creation with the JWT Decoder tool.

Related

JSON schema described by the values in a common model instead of the names defined in the schema

I am recommending to my client the use of a simplified data schema where the core document exchanged between parties via api has static mandatory information captured with identifiers, references, parties, dates, etc. and then has flexible objects within an array which can capture any data value which has taxonomy based metadata to describe what the value is.
The alternative method my client is considering, blows my mind. They are considering committing every piece of collected data to the schema with a self-describing value name.
We're talking about an insurance company - for liability and property cover types, there are over 300 questions between them. If this was a spreadsheet, that's a lot of columns. If a customer was only requesting property, then only 175 of those questions would be used and either the remainder are optional or null values.
What I'm proposing is, an example document received from a broker:
{
"characteristics" [
{
"category" : "business-activities",
"type" : "activities-hot-work",
"value" : "true"
},
{
"category" : "business-employees",
"type" : "employees-full-time",
"value" : "6"
}
]
}
Also, we could have another version of this document held at the API layer which uses the same categories and types but has the validation rules for the values received.
Example of validation version of the payload:
{
"characteristics" [
{
"category" : "business-activities",
"type" : "activities-hot-work",
"validation" : [
"value_type" : "boolean", "mandatory" : true
]
},
{
"category" : "business-employees",
"type" : "employees-full-time",
"validation" : [
"value_type" : "integer", "mandatory" : true
]
}
]
}
I would hope that using the two docs, the validation of resolving values to verification rules should be quite simple.
Is my logic making sense? What I want is to make the extending of what values are acceptable to receive to be a data management exercise instead of a new schema to be upgraded by all producers and consumers of a payload.
Additionally, I only want to receive the data I need for my request. I want the schema to be lightweight and flexible. I believe the schema does not need to be a flat version of an insurance product and every possible combination of questions.
I am thankful for your advice !

How can I get common response format for Lambda API?

I am using Node.js for AWS Lambda + API Gateway APIs.
I have multiple Lambda functions and each giving different response formats as it integrated multiple third party SDKs like Stripe/DynamoDB and all.
Is there any way to get common response for all the functions like below?
{
"success" : true,
"data" : { RESPONSEFROMLAMBDA },
"messages" : null,
"code" : 200,
"description" : "OK"
}
The third-party services your Lambda functions are using shouldn't have any bearing on the response format. You just need to update all the API Gateway endpoints to use a mapping template with this format.

API design for sub array of nested resources

I'm currently working on an API for an education app. There's a teacher resource and each teacher has a list of subjects that they teach. Currently, the GET teacher endpoint looks like this:
{
"first_name" : "Mister"
"last_name" : "Teacher"
"subjects" : [
{
"name" : "English",
"icons" : "/english-icon.png"
"id" : 1
},
{
"name" : "Math",
"icons" : "/math-icon.png"
"id" : 2
}
]
}
However, to me it doesn't make sense send the entire subject object when creating and updating the subjects, so the POST and PUT student endpoints accept parameters in the following form:
{
"first_name" : "Mister"
"last_name" : "Teacher"
"subject_ids": [1,2]
}
The inconsistency seems ugly, and it forces the client application to modify the format of an object before sending it to the server. Is there a more elegant solution?
First, you should include a link to each subject, not only the ID. This allows the client to navigate to a subject without having to build the URL from a pattern (which?) and the ID.
Second, your approach is fine if you think in think in representations. Both JSON structures are representations of the same resource. But they use different formats. In HTTP client and server would tell each other which format they send, request, or understand by using Content Negotiation.
If you do this, too, you are RESTful.

Socrata SODA within polygon is too complex

Using the Socrata SODA api for within_polygon an error is thrown stating that it is too complex.
https://www.dallasopendata.com/resource/x9pz-kdq9.json?$where=within_polygon(location,%20%27MULTIPOLYGON%20(((-96.79920%2032.77946,-96.807768%2032.7751,-96.7999%2032.76999,-96.79920%2032.77946)))%27)
{
"code" : "query.execution.queryTooComplex",
"error" : true,
"message" : "Only simple comparison filters are allowed",
"data" : {
"reason" : "validation.complex-filter"
}
}
Here is a working version:
https://data.cityofchicago.org/resource/yama-9had.json?$where=within_polygon(location,%20%27MULTIPOLYGON%20(((-87.63742446899414%2041.871733907393164,-87.64720916748047%2041.8687938398043,-87.6540756225586%2041.86080384272637,-87.64214515686035%2041.85287677909342,-87.63467788696289%2041.859141797891915,-87.62866973876953%2041.86329682898112,-87.63038635253906%2041.86789900978502,-87.64317512512207%2041.86380819876315,-87.64326095581055%2041.86591755588323,-87.63742446899414%2041.871733907393164)))%27)
You're using the old API endpoint, rather than the new one that supports within_polygon(...). You'll want to use this one instead. The query works as expected against that new endpoint:
https://www.dallasopendata.com/resource/5nug-crr9.json?$where=within_polygon(location,%20%27MULTIPOLYGON%20(((-96.79920%2032.77946,-96.807768%2032.7751,-96.7999%2032.76999,-96.79920%2032.77946)))%27)
For more details on the migration process, check out this entry in the API changelog.

What is the correct way to use the fields request parameter when getting a list of StorageObjects from Google Cloud Storage?

I would like to do a lookup in the storage using the JSON API client library and only retrieve the name and generation of each object matching a specific prefix but I am having issues with the fields request parameter.
Executing the following returns the expected objects.
Storage.Objects.List listObjects = null;
listObjects.setVersions(true);
listObjects.setPrefix(myprefix);
URL being created for the request in com.google.api.client.http.HttpRequest is https://www.googleapis.com/storage/v1beta2/b/mybucketname/o?prefix=myprefix&versions=true
However, when I add
listObjects.setFields("name,generation");
with URL created being https://www.googleapis.com/storage/v1beta2/b/mybucketname/o?fields=name,generation&prefix=myprefix&versions=true the below is returned:
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"location" : "fields",
"locationType" : "parameter",
"message" : "Invalid field selection name",
"reason" : "invalidParameter"
} ],
"message" : "Invalid field selection name"
}
How am I supposed to be specifying the fields I want returned? Is the hierarchy of the fields I'm specifying not correct?
Thank you!
Ref:
Verified the composition of the URL based on this: https://developers.google.com/storage/docs/json_api/v1/how-tos/performance#partial
I think what you want is:
fields=items(generation,name)
or with the full URL:
https://www.googleapis.com/storage/v1beta2/b/mybucketname/o?fields=items(generation,name)&prefix=myprefix&versions=true
The APIs Explorer is a great tool for experimenting with request fields like this. It will generate the proper fields for you.