Swagger - OpenAPI 3.0 : Defining additionalProperties in RequestBody to represent JSON - json

I have a REST API which accepts application/json in RequestBody. The keys in the json is not predefined. So I have used additionalProperties in swagger to define this JSON. Also, this json may hold JSONArray also.
The problem is, when additionalProperties is used, it is internally taken as Map<String, Object> in the generated java code. This map is deserialized to JSON by using Gson internally. During this conversion, the below json
{
"BooleanField": "true",
"ArrayField": [
"SDK ADD",
"SDK ADD 2"
],
"StringField": "SDK",
"IntField": "1"
}
is converted as
{
"BooleanField": "true",
"ArrayField": {
"myArrayList": [
"SDK ADD",
"SDK ADD 2"
]
},
"StringField": "SDK",
"IntField": "1"
}
The json array is put in myArrayList key. This causes input validation failure for this request. Is there any better way to solve this?

Related

JSON schema conditional check in JSON object within array

Here is the desired schema and json for illustration purpose. Please see the link below.
JSON Schema and JSON
{
"id": "123" ,
"ts": "1234567890",
"complex_rules":
[
{
"type":"admin",
"rule":{
"rights":"all",
"remarks": "some admin remarks"
}
},
{
"type":"guest",
"rights": "limited"
},
{
"type":"anonymous",
"rights": "blocked"
}
]
}
The 'complex_rules' is an array of json object:
With type either be a : "admin", "guest", "anonymous" and the 'type' attribute is MANDATORY.
Each object in array can have its own structure, but the type can be either of: "admin", "guest", "anonymous" only. No other type attribute is acceptable.
The conditions to evaluate:
The type of object in the array cannot re-occur in the array. (I know this seems to be not possible, so we can ignore this)
If attribute "rights" in the {type=admin object} with any value, then we cannot have "rights": "limited" or any value in {type=guest object}. The JSON Schema validation must complain about this.
Another twist, either object {type":"guest"}or {type":"anonymous"} can exist. Both types cannot coexist along with other types.
----Update
The above link is the solution this question.
In regards to 1 and 2:
You need to use a combination of if, then, and not keywords to construct the logic you require with the correct level of applicability.
In regards to 3:
The type of object in the array cannot re-occur in the array. (I know
this seems to be not possible, so we can ignore this)
Right, that's correct, it's not possible as of draft-7 JSON Schema.

How to output json in spring mvc

I am using Spring boot with mvc. I have a json schema for request and response. Basically the user posts data (in json) to a url, the controller does its logic and returns a json. I am having difficulty in returning the json. So far, I have a couple of views (in thymeleaf) with hardcoded responses which I dont want. I just want to use an object which I can edit and send back to the client. The response is very simple. This is the schema of the response:
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"message":{
"minLength":1,
"type":"string"
}
},
"required": [
"message"
]
}
I have an object of type response which conforms to my response json schema. I basically want to output this object to the client. But not sure how as my controller returns a String and this string is usually the name of the html page.
Add the #ResponseBody annotation to your controller method and it will use the returned value as a response rather than as a path to a page.
If you want that all methods of your controller return direct data (and not page paths), you can annotate your controller with #RestController rather than #Controller.

JSON for complex and simple data type

Im developing a WCF service that accepts JSON. My method signature accepts 2 parameters, a complex object and a simple type. For all intents and purposes below, assume "servicecredentials" has 2 properties, "username" and "password". I have valid JSON, but when I use a tool like postman I get the error "Expected to find an attribute with name 'type' and value 'object'. Found value 'array'.'"
How should this JSON be posted to the method?
<OperationContract()>
<WebInvoke(method:="POST")>
Function GetStuff(ByVal creds As servicecredentials, ByVal acctNum As String)
The JSON Im posting
[
{
"UserName": "someUSer",
"Password": "p#ssw0Rd"
},
{
"acctNum": "X12362"
}
]
The [] brackets indicate a JSON Array, the {} brackets indicate a JSON Object. If you encompass the array with the {} brackets it will be an object, which is what it seems to be looking for.
Example:
{
"data": [
{
"UserName": "someUSer",
"Password": "p#ssw0Rd"
},
{
"acctNum": "X12362"
}
]
}
The exact internal structure of the JSON depends on how the method will process the data. The error is simply stating that the JSON is not encompassed by an object.

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.

How to use JMS Message Transformation in ActiveMQ with Stomp/JSON

I am sending messages in JSON format to an ActiveMQ server. I am trying to use JMS Transformation to transform the JSON encoded object into a true Java Object in hopes of being able to use selectors on the data inside.
Here is a link to the documentation on Stomp and Message Transformation.
Here is a link to a discussion on the patch where someone shows an example of a legal JSON object
The format of the JSON objects I am sending (in pretty print) are similar to this:
{
"msg": {
"flag1" : "value1",
"flag2" : "value2"
}
}
The messages arrive in the message queue, but with the transformation-error property set to 'msg : msg'.
The only format accepted by the transformation jms-map-json or jms-object-json is a simple Map format, which in JSON is:
{"map" :
{"entry" :
[
{ "string1": [ "key1", "value1" ] },
{ "string2": [ "key2", "value2" ] }
]
}
}
This is the same format shown in the discussion forum. This format represents a name/value pair map object in java.
Selectors are only usable on Properties and Headers.
you can use any JSON notation for your jms-object-json transformations as long as XStream can handle it. You can take a look at test cases for some examples. There, we use SamplePojo class:
https://svn.apache.org/repos/asf/activemq/trunk/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/SamplePojo.java
which is properly annotated so it can be represented with the following JSON
{"pojo":{
"name":"Dejan",
"city":"Belgrade"
}}
You can try using the same approach for your classes.
Hope this helps,
Dejan
It should be mentioned that ActiveMQ version must at least 5.8, because with 5.6 version I had problem when transformation just did not work.