Swagger Error A deterministic version of a JSON Schema object - json

This is the Schema definition.
serviceArea: [{
states: [{
type: String
}],
districts: [{
type: String
}],
cities: [{
type: String
}]
}]
This is the swagger definition.
serviceArea:
- states:
- type: String
districts:
- type: String
cities:
- type: String
I am getting the above mentioned error. Please help. Thanks in advance.
Here is the swagger editor in the browser.

Assuming serviceArea is supposed to be an object with properties states, districts and cities, the definition should look like this:
serviceArea:
type: object
properties:
states:
type: string
districts:
type: string
cities:
type: string
UPDATE with regard to OP's comments:
It's an array of arrays.
An array of arrays is described as:
serviceArea:
type: array
items:
type: array
items:
type: string
Another error is here:
type:
- number
- "null"
type must be a single type such as type: number, not an array of types. Also, the OpenAPI Specification 2.0 does not support the null type. Some tools use the extension property x-nullable: true to indicate nullable types, so you can try this:
type: number
x-nullable: true
nullable will be supported natively in the next version, OpenAPI 3.0.

Related

Define example on Swagger of array with arrays [duplicate]

I am using Swagger OpenAPI Specification tool. I have a string array property in one of the definitions as follows:
cities:
type: array
items:
type: string
example: "Pune"
My API produces JSON result, so Swagger UI displays the following example for the response:
{
"cities": [
"Pune"
]
}
How can I add multiple example values for the cities array? Expecting the result as:
{
"cities": [
"Pune",
"Mumbai",
"Bangaluru"
]
}
Tried comma-separated strings in the example key like below:
cities:
type: array
items:
type: string
example: "Pune", "Mumbai", "Bangaluru"
But the Swagger Editor shows an error, "Bad indentation".
Is there any way to specify multiple values in the example key?
Update
User Helen below has given the correct answer. I had an indentation problem hence there were nested arrays (2d arrays)
Correct way:
cities:
type: array
items:
type: string
example:
- Pune
- Mumbai
My way (which was wrong)
cities:
type: array
items:
type: string
example:
- Pune
- Mumbai
Look for the indentation of the example key in the above two cases which makes the difference, its YAML indentation matters.
To display an array example with multiple items, add the example on the array level instead of item level:
cities:
type: array
items:
type: string
example:
- Pune
- Mumbai
- Bangaluru
# or
# example: [Pune, Mumbai, Bangaluru]
In case of array of objects, the example would look like this:
type: array
items:
type: object
properties:
id:
type: integer
name:
type: string
example:
- id: 1
name: Prashant
- id: 2
name: Helen
paths:
/products_1:
get:
responses:
'200':
description: "XYZ"
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/pro'
example:
- name : "Laptop"
dist : "HP LAPTOP"
- name : "Mobile"
dist : "Apple Mobile"
components:
schemas:
pro:
type: object
properties:
prodName:
type: string
example: "Laptop"
prodDesc:
type: string
example: "Produc Description"
For openapi version - 3.0.0+
major:
type: array
items:
type: string
enum:
- Accounting
- Business Contacts
- Economy
- Finance
- Graphic Design
- International Business Administration
- International Relations
- Law
- Marketing
- others
- Political Science
- Statistics

Swagger How to encode JSON?

I get the response in the form of an associative array encoded in json, which contains 3 elements of the boolean, integer and string types.
responses:
200:
description: Success
content:
application/json:
schema:
properties:
data:
type: object
properties:
success:
type: boolean
example: true
code:
type: integer
example: 200
msg:
type: string
example: "Success!"
This is what the answer looks like:
{"success":true,"code":200,"msg":"\u0423\u0441\u043f\u0435\u0445!"}
But I don't understand how to decode the msg element. Tips?
I found the answer. In the place where we return the encoded response, we need to add the constant JSON_UNESCAPED_UNICODE.

Is it possible to 'inject' reference to a JSON Schema

Considering I need to refer to a json with the following format:
{
"data": {
"type": "ObjectA"
}
}
When I write JSON schema (or more specifically, schema object of OpenAPI Specification v3.0.3) for this json request, I write
components:
schemas:
Data:
type: object
required:
- data
properties:
data:
$ref: '#components/schemas/ObjectA'
ObjectA:
type: object
properties:
type:
type: string
ObjectB:
type: object
properties:
type:
type: string
some_properties:
type: string
... and I refer to it using $ref: '#components/schemas/Data'.
However now there is the other json to deal with, which is very similar to the one above except that the object in data property is not of type ObjectA, it is ObjectB instead.
{
"data": {
"type": "ObjectB",
"some_properties": "which is different from ObjectA"
}
}
Is there a way for me to reuse the schemas for Data above without creating a new schema (so it is like injecting #components/schemas/ObjectA or #components/schemas/ObjectB into Data whenever needed)?
I have considered using oneOf but it does not fit since only a specific object is valid for a specific API endpoint (even though all are under the data property) instead of any one of the available objects.
In your simple example, it seems unnecessary to re-use the simple Data definition. However, assuming your actual structure is more complex you could combine the general attributes with the specific ones via allOf, e.g.
components:
schemas:
BaseData:
type: object
required:
- data
properties:
data:
type: object
properties:
type:
type: string
required:
- type
DataA:
allOf:
- $ref: '#components/schemas/BaseData'
- type: object
properties:
data:
$ref: '#components/schemas/ObjectA'
DataB:
allOf:
- $ref: '#components/schemas/BaseData'
- type: object
properties:
data:
$ref: '#components/schemas/ObjectB'
ObjectA:
type: object
properties:
type:
const: ObjectA
ObjectB:
type: object
properties:
type:
const: ObjectB
some_properties:
type: string
required:
- some_properties
Depending on the actual complexity, the schema might be easier to read/maintain if the shared parts are simply duplicated.

Swagger schema with additionalProperties fails

I'd like to post a JSON object within the body of a REST API call. The attribute dataof this DATA object contains a mandatory timestampattribute and then a series of various attributes depending on the source of the Data object. As far as I understood additionalPropertiesis meant for this and defaults to falseor specifies the schema object for every non-defined attribute.
Following Swagger YAML
/my/path:
post:
tags: [Tag]
description: Description
parameters:
- name: data
in: body
description: The actual data.
required: false
type: object
schema:
$ref: "#/definitions/Data"
definitions/
Data:
type: object
properties:
source:
type: string
data:
type: object
properties:
timestamp:
type: string
format: date-time
additionalProperties:
type: string
should pass both objects send:
{
"source": "A",
"data": {
"timestamp": "2016-10-26T01:12:40.329Z",
}
}
and:
{
"source": "B",
"data": {
"timestamp": "2016-10-26T01:12:40.329Z",
"newProp":"newValue"
}
}
However all I receive is a validation Error:
ValidationError: child "data" fails because ["test" is not allowed]
Is there anything I'm doing wrong or am I misinterpreting the attribute described at the docs:
http://swagger.io/specification/
I'm not sure if your solution got your past the problem. I see a few differences from your original problem schema:
timestamp now uses date instead of datetime format.
timestamp is now required.
additionalProperties is set to true.
However, there's a set of obscure limitations in Swagger with respect to additionalProperties, which we've documented in detail here.
Essentially, while your original schema is perfectly valid according to the Swagger specification, the swagger-core Java library won't process it correctly. It will discard either your explicitly defined timestamp property, or will discard additionalProperties.
The fix, surprisingly, is to extract the embedded schema for the data property to its own top-level schema definition:
definitions:
Data:
type: object
properties:
source:
type: string
data:
$ref: "#/definitions/DataValues"
DataValues:
type: object
properties:
timestamp:
type: string
format: date-time
additionalProperties:
type: string
I think your revised schema won't work correctly, because additionalProperties boolean values of true or false are ignored by swagger-core. Apparently this was an oversight in the specification; Swagger didn't intend to support this aspect of JSON Schema.
I actually figured it out myself, for reference:
definitions/
Data:
type: object
properties:
source:
type: string
data:
required:
- timestamp
type: object
properties:
timestamp:
type: string
format: date
additionalProperties: true

Swagger Yaml schema definition for object without a fixed property list

I am implementing an API-first application with the help of Swagger. One of the most important objects to be returned is a DICOM object, which returns a collection of attributes with flexible names, for example:
{
"00080005": {"vr":"CS","Value":["ISO_IR 100"]},
"00080020": {"vr":"DA","Value":["20160602"]},
"00080030": {"vr":"TM","Value":["171855.7490"]},
"00080050": {"vr":"SH","Value":["1234"]},
"00080090": {"vr":"PN","Value":[{"Alphabetic":"Parikh MD^Anush^M"}]}
}
So I cannot know the name of all the attributes in advance (00080005, 00080030, etc.) although the file structure is very uniform.
My concrete question is: what would be the schema definition for such JSON document.
I have tried the following without success:
definitions:
DicomMetadataJson:
type: object
patternProperties:
^\d{8}:
type: object
but the Swagger Editor returns an error like:
code: "OBJECT_ADDITIONAL_PROPERTIES"
message: "Additional properties not allowed: patternProperties"
description: "A deterministic version of a JSON Schema object."
OpenAPI (fka. Swagger) use only a subset of JSON Schema v4 which, unfortunately, do not propose patternProperties.
But given the provided example is a map, you can describe it using additionalProperties:
swagger: "2.0"
info:
version: 1.0.0
title: Hashmap
paths: {}
definitions:
DicomMetadataJson:
additionalProperties:
properties:
vr:
type: string
Value:
type: array
items:
type: string
The key is not defined and is supposed to be a string (therefore you cannot enforce it's format).
Note that SwaggerUI Swagger UI do not render them for now.The issue is tracked here https://github.com/swagger-api/swagger-ui/issues/1248
In the meanwhile you can use this trick define a non required property (default in the example below) of the same type of the map's objects and give some hint within the description:
swagger: "2.0"
info:
version: 1.0.0
title: Hashmap
paths: {}
definitions:
MetaData:
properties:
vr:
type: string
Value:
type: array
items:
type: string
DicomMetadataJson:
description: 'A <string,MetaData> map, default key is only for documentation purpose'
properties:
default:
$ref: '#/definitions/MetaData'
additionalProperties:
$ref: '#/definitions/MetaData'
Concerning the quote The schema exposes two types of fields. Fixed fields, which have a declared name, and Patterned fields, which declare a regex pattern for the field name. Patterned fields can have multiple occurrences as long as each has a unique name., it concerns the format of the OpenAPI specification itself and not the objects used by the API described with an OpenAPI specification.