What is the best practice of testing JSON data? - json

I'm developing a server-side RESTful application which serves json data for its client applications. And I have to test so many various json outputs.
Each json has many properties and their validation methods are different like below a sample json.
So such my use-case, do you know good libraries or web services to test json data flexibly?
{
"system": { // data structure validation
"time": 1234566, // data type validation
"version": "0.0.1" // string matching validation
},
"app": { // data structure validation
"id": "1234", // string matching validation
"command": "do something", // string matching validation
"data": { // data structure validation
"hoge": "xxx", // data type validation
"fuga": 123 // data type validation
}
}
}

What do you mean by validating? validating the JSON structure or the data inside your JSON object?
To validate the structure you can parse it to another datatype like dictionary and see if you get any error while.
But to validate the data inside the object you need to validate each object in a very specific way for that object.

Use this link Just Place your JSON code and Test it. Quite easy.

Related

Problem generating Spec for JSON Response type of Array of Users

I've got a Go project, exposing REST CRUD APIs, for a Mongo collection. I'm using go-swagger to generate the swagger spec. However, I'm having trouble getting the JSON response to look like I want without breaking the go-swagger spec generator.
I'm trying to use go-swagger to generate a swagger-spec from annotations on go code. I'd like to see if I can make the response just be a JSON Array of Users, like below.
Is there a way to adjust the json annotation on the User struct to produce the desired result?
[
{"id": "5d8e9aaca00ef6123c989f69", "user_name": "zbeeblebrox"},
{"id": "5d8e9ab1a00ef6123c989f6a", "user_name": "another_user"}
]
Below is what I'm getting, understandably, a JSON object, containing key "data", with a value of an Array of User objects.
I've tried redefining the swagger response struct to be an alias of type []*User, which creates the right response body, but it breaks the go swagger generator.
{
"data": [
{"id": "5d8e9aaca00ef6123c989f69", "user_name": "zbeeblebrox"},
{"id": "5d8e9ab1a00ef6123c989f6a", "user_name": "another_user"}
]
}
Here's some code.
// swagger:model
type User struct {
Id *primitive.ObjectID `json:"id,omitempty" bson:"_id,omitempty"`
UserName string `json:"user_name" bson:"user_name"`
}
// HTTP status code 200 and an array of repository models in data
//swagger:response usersResp
type swaggUsersResp struct {
// in:body
Data []*User `json:"data"`
}
I also tried doing it as an alias, which provides the desired JSON response, but breaks Go-Swagger code generation. I suspect this is because the swagger:response annotation is expected to be on a struct, not an alias.
// swagger:response usersResp
type swaggUsersResp = []*User

How to define schema arbitrary JSON object?

I am trying to define a API using OAS v2 that will return a payload along with some metadata.
In other words, the response to the API will be:
{
"metadata":[
{
"key" :"key1",
"value": "value1"
}
],
"payload": {Valid JSON}
}
The payload can be anything, and different for different scenarios, the only constraint being it will be a valid JSON format. So, at this point in time, I would like to define it just as a JSON object without defining the field level details.
How can I do that in OAS2/JSON schema?
Thanks in advance.
In this case you can use an empty schema ({}) for payload.
JSON Schema relies on valid JSON value and you won't be able to supply it if your response is a malformed JSON.
If payload value is malformed, whole response will not be a valid JSON.
In other words, this issue is out of JSON Schema scope, but rather in scope of your response decoder (that should fail on malformed response body).

How to read invalid JSON format amazon firehose

I've got this most horrible scenario in where i want to read the files that kinesis firehose creates on our S3.
Kinesis firehose creates files that don't have every json object on a new line, but simply a json object concatenated file.
{"param1":"value1","param2":numericvalue2,"param3":"nested {bracket}"}{"param1":"value1","param2":numericvalue2,"param3":"nested {bracket}"}{"param1":"value1","param2":numericvalue2,"param3":"nested {bracket}"}
Now is this a scenario not supported by normal JSON.parse and i have tried working with following regex: .scan(/({((\".?\":.?)*?)})/)
But the scan only works in scenario's without nested brackets it seems.
Does anybody know an working/better/more elegant way to solve this problem?
The one in the initial anwser is for unquoted jsons which happens some times. this one:
({((\\?\".*?\\?\")*?)})
Works for quoted jsons and unquoted jsons
Besides this improved it a bit, to keep it simpler.. as you can have integer and normal values.. anything within string literals will be ignored due too the double capturing group.
https://regex101.com/r/kPSc0i/1
Modify the input to be one large JSON array, then parse that:
input = File.read("input.json")
json = "[#{input.rstrip.gsub(/\}\s*\{/, '},{')}]"
data = JSON.parse(json)
You might want to combine the first two to save some memory:
json = "[#{File.read('input.json').rstrip.gsub(/\}\s*\{/, '},{')}]"
data = JSON.parse(json)
This assumes that } followed by some whitespace followed by { never occurs inside a key or value in your JSON encoded data.
As you concluded in your most recent comment, the put_records_batch in firehose requires you to manually put delimiters in your records to be easily parsed by the consumers. You can add a new line or some special character that is solely used for parsing, % for example, which should never be used in your payload.
Other option would be sending record by record. This would be only viable if your use case does not require high throughput. For that you may loop on every record and load as a stringified data blob. If done in Python, we would have a dictionary "records" having all our json objects.
import json
def send_to_firehose(records):
firehose_client = boto3.client('firehose')
for record in records:
data = json.dumps(record)
firehose_client.put_record(DeliveryStreamName=<your stream>,
Record={
'Data': data
}
)
Firehose by default buffers the data before sending it to your bucket and it should end up with something like this. This will be easy to parse and load in memory in your preferred data structure.
[
{
"metadata": {
"schema_id": "4096"
},
"payload": {
"zaza": 12,
"price": 20,
"message": "Testing sendnig the data in message attribute",
"source": "coming routing to firehose"
}
},
{
"metadata": {
"schema_id": "4096"
},
"payload": {
"zaza": 12,
"price": 20,
"message": "Testing sendnig the data in message attribute",
"source": "coming routing to firehose"
}
}
]

TJSONUnMarshal: how to track what is actually unmarshalled

Is there another way to track what is unmarshalled than write own reverter for each field?
I'm updating my local data based on json message and my problem is (simplified):
I'm expecting json like
{ "items": [ { "id":1, "name":"foobar", "price":"12.34" } ] }
which is then unmarshaled to class TItems by
UnMarshaller.TryCreateObject( TItems, TJsonObject( OneJsonElement ), TargetItem )
My problem is that I can't make difference between
{ "items": [ { "id":1, "name":"", "price":"12.34" } ] }
and
{ "items": [ { "id":1, "price":"12.34" } ] }
In both cases name is blank and i'd like to update only those fields that are passed on json message. Of course I could create a reverted for each field, but there are plenty of fields and messages so it's quite huge.
I tried to look REST.Jsonreflect.pas source, but couldn't make sense.
I'm using delphi 10.
In Rest.Json unit there is a TJson class defined that offers several convenience methods like converting objects to JSON and vice versa. Specifically, it has a class function JsonToObject where you can specify options like for example ignore empty strings or ignore empty arrays. I think the TJson class can serve you. For unmarshalling complex business objects you have to write custom converters though.
Actually, my problem was finally simple to solve.
Instead of using TJSONUnMarshal.tryCreateObject I use now TJSONUnMarshal.CreateObject. First one has object parameters declared with out modifier, but CreateObject has Object parameter var modifier, so I was able to
create object, initalize it from database and pass it to CreateObject which only modifies fields in json message.

How to express "arbitrary JSON" in swagger-spec?

Let's say I have a REST service that can accept any arbitrary JSON in the request body. How do I model this using swagger-spec?
I thought about Model Objects, but I could only think to wrap the arbitrary JSON (as a string) within a container JSON object, like {"payload": "{ some JSON object serialized to a string }"}, which isn't really useful.
Or, is there some other way to express that an endpoint can receive arbitrary JSON in the request body?
Model the request's body payload as parameters with schema of just "type": "object". The swagger UI editor will then prompt the user with a large textarea containing {} which they can populate with a JSON object.
"/endpoint": {
"post": {
"parameters": [
{
"description": "Arbitrary JSON object payload",
"in": "body",
"name": "body",
"required": true,
"schema": {
"type": "object"
}
}
]
}
Swagger tries to be deterministic when it comes to APIs, so what you're asking is not directly supported.
The only way I can think of to achieve what you want is to set the "consumes" property to "application/json" and add a "body" parameter of type string. This would in theory say that only JSON should be sent, but in effect, any string could be sent.
Also, this may break some third party tools if they'd try to convert to string to a JSON object before sending it to the server.