YAML Swagger typing for key name - json

my question maybe seems to be easy, but I can't implement this on my YAML files. I would like to generate the API responses from YAML files, but I've a problem. In my JSON files, there's a key named 'type', like this:
"type": {
"id": 5,
"name": "TRONTON",
}
This key never been returned from the YAML file, because I think it's have a colliding with type parameters on YAML format itself for describing datatypes. The full code of YAML file is this:
components:
schemas:
myapi:
type: object
properties:
type:
type: object
properties:
id:
type: number
name:
type: string
Any one can help me? Thanks

Related

Message examples in OpenAPI 3 YAML specification

OpenAPI v3 offers using JSON or YAML format.
I prefer using YAML to create API specifications. YAML's readability is much better for me as an API designer.
However, sometimes I need to embed a message example whose type is object. I usually have the examples in JSON format. So I would do the following:
examples:
singlePet:
summary: Single pet
description: A request containing a single pet
value: |
{
"pets" : [
{
"petType" : "DOG",
"name" : "Ben"
}
]
}
However, such value is a string, not an object, whereas OpenAPI expects an object.
Do we have any options to embed a JSON as an example value in the YAML specification?
Currently, I convert the JSON to YAML and embed the YAML:
examples:
singlePet:
summary: Single pet
description: A request containing a single pet
value:
pets:
- petType: DOG
name: Ben
YAML is a superset of JSON. This means you can use JSON syntax for objects and arrays within a YAML document.
In your first example, you can just remove the | after the value: to keep the example value as an object.
The following are equivalent:
examples:
singlePet:
summary: Single pet
description: A request containing a single pet
value:
{
"pets" : [
{
"petType" : "DOG",
"name" : "Ben"
}
]
}
examples:
singlePet:
summary: Single pet
description: A request containing a single pet
value:
pets:
- petType: DOG
name: Ben
Alternatively, you can use externalValue to point to an external file containing sample JSON.
examples:
singlePet:
summary: Single pet
description: A request containing a single pet
externalValue: 'https://api.example.com/docs/examples/pet.json'

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 Error A deterministic version of a JSON Schema object

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.

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.