type": "array",
"items": {
"type": "string",
"enum": ["MALE","FEMALE","WORKER"]
}
or
type": "array",
"items": {
"type": "string",
},
"enum": ["MALE","FEMALE","WORKER"]
?
Nothing in the spec about this. The goal is of course to get swagger-ui to show the enum values.
It will depend on what you want to enum:
Each enum value MUST be of the described object type
in first case a String
in second one an Array of String
First syntax means These are the possible values of the String in this array
AnArray:
type: array
items:
type: string
enum:
- MALE
- FEMALE
- WORKER
This array can contain multiple String, but each String must have MALE, FEMALE or WORKER value.
Second one means These are the possible values of this Array
AnotherArray:
type: array
items:
type: string
enum:
-
- FEMALE
- WORKER
-
- MALE
- WORKER
Each enum value is therefore an array. In this example, this array can only have to possible value ["FEMALE","WORKER"] and ["MALE","WORKER"].
Unfortunately even if this syntax is valid, no enum values are shown in Swagger UI.
The first case is correct and these days swagger-ui generates a multiple-choise select of the enum values.
Related
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
So this is the response structure that I have.
The same identifier attribute, can have a data associated with it that can be a list of other objects.
The outermost table is list of other view types and the inner table is list of rows, if that makes sense.
{
"identifier": "table",
"data": [
{
"identifier": "top_view",
"data": [
{
"value": "this is top header type view"
}
]
},
{
"identifier": "table",
"data": [
{
"value": "this is a first row in a table"
},
{
"value": "this is a second row in a table"
},
{
"value": "this is a third row in a table"
}
]
},
{
"identifier": "bottom_view",
"data": [
{
"value": "this is a footer type view"
}
]
}
]
}
Can I use swifts Codable to decode this in anyway? Solutions for this type of decoding generally involve having an enum around differentdata and using this to inject the correct type associated with it. But in this case, the identifier is the same.
Let me know if I need to add in more details.
Edit 1 -
Well, I am trying to build a new app that has a backend driven UI.
This is just the response of a screen within the app.
To explain more about the json - The outermost table is a tableview that can have 3 cells - the first one being the top header, second a table(that again has 3 cells that each consists of label) and the third is a bootom footer (Not to be confused with a tableviews default header footer).
I understand that the json might be flawed in itself but initially I had hoped that it would work by employing a nested json structure (hence the use of same data key)
The value of data in this case can change across different components.
I think I understand what you are trying to achieve (from what you were saying about the enum). This is something to get you started --
struct TableableData: Codable {
enum ViewType {
case top(values: [String])
case bottom(values: [String])
case table(data: [TableableData])
init?(identifier: String?, data: [TableableData]) {
switch identifier {
case "top_view": self = .top(values: data.compactMap{ $0.value })
case "bottom_view": self = .top(values: data.compactMap{ $0.value })
case "table": self = .table(data: data)
default: return nil
}
}
}
let identifier: String?
let value: String?
let data: [TableableData]!
var view: ViewType? {
ViewType(identifier: identifier, data: data)
}
}
I had to make all fields optional to quickly test it against your json, it works. I would suggest using init from decoder to replace optional with empty array or something.
I am looking to represent the following JSON Object in OpenAPI:
{
"name": "Bob",
"age": 4,
...
}
The number of properties and the property names are not fully predetermined, so I look to use additionalProperties. However, I'm not too certain how it would be represented through OpenAPI/Swagger 2.0. I tried this:
Person:
type: object
additionalProperties:
type:
- int
- string
or the JSON equivalent:
{
"Person": {
"type": "object",
"additionalProperties": {
"type": ["int", "string"]
}
}
}
but that didn't quite work. Is there any way to keep the structure of the JSON Object I want to represent, for specifically strings and integers, and not arbitrary object types?
OpenAPI 3.1
In OpenAPI 3.1, the type keyword can take a list of types:
Person:
type: object
additionalProperties:
type: [string, integer]
OpenAPI 3.x
OpenAPI 3.0+ supports oneOf so you can use:
Person:
type: object
additionalProperties:
oneOf:
- type: string
- type: integer
OpenAPI 2.0
OpenAPI 2.0 does not support multi-type values. The most you can do is use the typeless schema, which means the additional properties can be anything - strings, numbers, booleans, and so on - but you can't specify the exact types.
Person:
type: object
additionalProperties: {}
This is equivalent to:
Person:
type: object
In InfluxDB, can you post multidimensional hash values to the database?
For example, this hash:
{
"field1": "value1",
"field2": {
"field2a": "value2a",
"field3a": "value3a"
}
}
If you can, how do you do this? When I try via the http admin interface, it neither errors out or returns success.
Multidimensional values are not supported by InfluxDB. Points have fields that are a set of key-value pairs. Currently, values can only be of type float, integer, boolean, or string. InfluxDB has no concept of nested key-values. The relevant source is here.
A workaround would be to store the JSON as a string literal by escaping all double quote characters (e.g. \"). Then implementing whatever functionality required in the client.
curl -h -XPOST 'http://localhost:8086/write' -d '
{
"database": "test",
"retentionPolicy": "default",
"points": [
{
"name": "json_blob",
"tags": {
"tag1": "tag-value-a",
"tag2": "tag-value-b"
},
"fields": {
"value": "{\"field1\":\"value1\",\"field2\":{\"field2a\":\"value2a\",\"field3a\":"value3a\"}}"
}
}
]
}'
I have given JSON and cannot parse partial data. It seems dictionary into dictionary:
{
"products": [
{
"id": 6796,
"title": "my title",
"description": "desc",
"code": "12345",
"valueType": "null",
"discounts": [
{
"minPrice": null,
"maxPrice": null,
"value": 20,
"avail": false
}
]
}
]
}
I am using the latest version of RESTKit but I cannot properly parse under discounts.
my RestKit settings are:
responseMapping.addAttributeMappingsFromDictionary([
"id" : "id",
"code" : "code",
"title" : "title",
"valueType" : "valueType",
"description" : "desc",
"discounts.minPrice" : "minPrice",
"discounts.maxPrice" : "maxPrice",
"discounts.value" : "value",
"discounts.avail" : "avail",
])
but all values below discounts always return Nil. What I am doing wrong?
You can't directly map using discounts.XXX because discounts is an array and you have no way to index into that array and extract a single value.
You either need to change the source JSON to compress the values out of the dictionary, or create a custom object that you can map each item in the discounts array to.
Technically you could map the whole discounts array, which would give you an array of dictionaries, that you could then unpack in the setter method, but the array of custom objects is usually a better approach.