How to define this array of objects in OpenAPI? - swagger

How to write an OpenAPI definition for the following JSON?
Bazically it is an array consisting of two objects with similar attributes but different fields.
[
{
"studentname": "somename",
"studentrollno": "somerollno",
"studentsubjects": [
{
"level": "third",
"physics": "xyz",
"maths": "somevalue"
},
{
"level": "second",
"physics": "abc",
"maths": "somevalue11"
}
],
"studentresult": "pass"
},
{
"studentname": "newname",
"studentrollno": "newrollno",
"studentsubjects": [
{
"level": "third",
"physics": "xyz",
"maths": "somevalue"
},
{
"level": "second",
"physics": "abc",
"maths": "somevalue11"
}
],
"studentresult": "fail"
}
]
type: array
items:
type: object
properties:
studentname:
type: string
example: somename
studentrollno:
type: string
example: somerollno
studentsubjects:
type: array
items:
type:object
properties:
level:
type: string
example: third
physics:
type: string
example: xyz
maths:
type: string
example: somevalue
type: object
This is how i have written , i have written it for the first object in studentsubjects array , but not able to code it for second object in the same array , when i am trying to do it , it is throwing me erro saying duplication of type at last line

Related

Associative array in Swagger (OpenApi 3.0.0)

I have an API that always answers with an associative array where there is only one entry with key "data" containing the final result. The result can be an object or array of objects. This is API output:
{
"data": {
"id": 1,
"name": "product1 name",
"type": "type a",
"created_at": "2011-09-28T13:20:15+02:00"
}
}
{
"data": [
{
"id": 1,
"name": "product1 name",
"type": "type a",
"created_at": "2010-09-28T13:20:15+02:00"
},
{
"id": 6,
"name": "product6 name",
"type": "type f",
"created_at": "2010-09-28T13:20:28+02:00"
},
{
"id": 17,
"name": "product17 name",
"type": "type Q",
"created_at": "2010-09-28T13:20:42+02:00"
}
]
}
How can I get swagger to show data which is the name of the key, in the docs?
As for now I only get nested array in swagger:
[
{
"id": 1,
"name": "product1 name",
"type": "type a",
"created_at": "2010-09-28T13:20:15+02:00"
}
]
[
[
{
"id": 1,
"name": "product1 name",
"type": "type_a",
"created_at": "2010-01-01T18:21:20+02:00"
}
]
]
I need the data key to be shown in swagger as it comes back from the API. Is it doable? I wasn't able to find any solution to this yet...:/
parts of my yaml file:
openapi: "3.0.0"
info:
version: 1.0.0
paths:
/products/:
get:
summary: List all available products
operationId: listProducts
tags:
- products
responses:
200:
description: Array of products
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Products"
/products/{product_id}:
get:
summary: Get specific product
operationId: showProductById
tags:
- products
parameters:
- name: product_id
in: path
required: true
description: The id of the product to retrieve
schema:
type: integer
format: int32
example: 1
responses:
200:
description: Product object
content:
application/json:
schema:
type: array
properties:
datar: string
items:
$ref: "#/components/schemas/Product"
components:
schemas:
Product:
type: object
properties:
id:
type: integer
format: int32
example: 10
name:
type: string
example: "producta name"
type:
type: string
example: "type a"
created_at:
type: string
format: date
example: "2010-01-01T18:21:20+02:00"
Products:
type: array
items:
$ref: "#/components/schemas/Product"
Any help will be much appreciated:)
Cheers
try with a "additionalProperties" in a intermediate layer for a assoc-array, source: https://swagger.io/docs/specification/data-models/dictionaries/
components:
schemas:
Product:
type: object
properties:
id:
type: integer
format: int32
example: 10
name:
type: string
example: "producta name"
type:
type: string
example: "type a"
created_at:
type: string
format: date
example: "2010-01-01T18:21:20+02:00"
ArrayOfProduct:
type: object
additionalProperties:
$ref: "#/components/schemas/Product"
Products:
type: object
properties:
data:
type: object
$ref: "#/components/schemas/ArrayOfProduct"

Implement dynamic values

I am trying to implement this request:
curl -ik -X POST "https://<HOST_IP>/api/v1/roles/" -H "accept: application/json" -H "x-access-token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwidXNlcl9pZCI6IjVlMGM0Nzg0OGZiMDNhMzJmMTc0Nzc0NSIsInNvdXJjZSI6bnVsbCwicGVybWlzc2lvbnMiOnsiQUxMIjpbdHJ1ZV19LCJpYXQiOjE1Nzc4NzY0ODIsImV4cCI6MTU3NzkxOTY4Mn0.Z-WJ7ouQ5XdDqNvxMgTc-74qgW4sShtJrqTaEH-rykA" -H "Content-Type: application/json" -d "{\"users\":[{\"id\":\"5e0c47848fb03a32f1747745\",\"title\":\"admin\"}],\"groups\":null,\"permissions\":{\"ISSUES\":[\"All\"]},\"devicePermissions\":null,\"name\":\"role name\",\"description\":\"\"}"
I have this request body:
"users": [
{
"id": "5e0c47848fb03a32f1747745",
"title": "admin"
}
],
"groups": [
{
"id": "5e0c8f0d8a2c1676ed67fd2e",
"title": "asgsagas"
}
],
"permissions": {
"ISSUES": [
"All"
],
"RULES": [
"All"
]
},
"devicePermissions": null,
"name": "gasgag",
"description": ""
}
where under "permissions" object I can add (optional) additional string arrays , But I am struggling how to implement it, should I implement all options? how can I make it generic?
This is how I implemented it:
permissions:
type: object
properties:
ISSUES:
type: array
items:
type: string
example: "All"
KNOWLEDGE_EXPLORER:
type: array
items:
type: string
example: "Archive"
ANALYSIS_AND_REPORTS:
type: array
items:
type: string
example: "All"
DEVICES:
type: array
items:
type: string
example: "All"
CREDENTIALS_MANAGEMENT:
type: array
items:
type: string
example: "All"
BACKUPS:
type: array
items:
type: string
example: "All"
ABOUT:
type: array
items:
type: string
example: "All"
INTEGRATIONS:
type: array
items:
type: string
example: "All"
USERS:
type: array
items:
type: string
example: "All"
AUDIT:
type: array
items:
type: string
example: "All"
APPLICATION_SETTINGS:
type: array
items:
type: string
example: "All"
DEV_TOOLS:
type: array
items:
type: string
example: "All"
OTHER:
type: array
items:
type: string
example: "All"
I am using java in order to use this api request and I can see that maybe my implementation is not correct.
This is the expected response:
{
"ok": true,
"code": "",
"message": "Create was success",
"hasException": false,
"exception": null,
"errors": [],
"info": null,
"content": {
"devicePermissions": {
"showAll": true,
"labels": []
},
"_id": "5e0cb0ed8a2c1676ed67fd56",
"name": "devices_delete_labels_role_278932055218587",
"description": "New Role added to the system",
"permissions": {},
"updatedAt": "2020-01-01T14:47:09.792Z",
"createdAt": "2020-01-01T14:47:09.792Z",
"__v": 0
}
}

How to normalize this recursive nested JSON

Having a bit of an issue trying to normalise the my payload that contains a nested schema of the same type as the parent using Normalizr
For example
{
id: 123,
sections:{
section: [{
id: 1,
name: "test",
sections: {
section: {
id: 125,
name: "test125"
}
}
}, {
id: 2,
name: "test2"
sections: {
section: [
{
id: 124,
name: "test124"
}
]
}
}, {
id: 3,
name: "test3"
}]
}
}
In the above json structure, nested section may be an object or an array.
I had a similar issue with nested comments. Here's how I solved it:
export const comment = new schema.Entity("comment", {}, {
idAttribute: "key"
})
comment.define({
user: user,
reactions: {
data: [reaction]
},
children: [comment]
})
export const post = new schema.Entity("post", {
user: user,
files: [image],
comments: {
data: [comment]
},
reactions: {
data: [reaction]
}
}, {
idAttribute: "key"
})
Basically, I define comment as a new entity before I use it in its own entity definition. The other schemas I define as usual, in the constructor (see the post schema for an example). Hope this helps.
Here is a jq filter which will normalize the data:
def enumerate:
if type=="array" then .[] else . end ;
def sectionids:
[ .sections.section | enumerate | .id // empty | tostring ]
| if .==[] then {} else {sections:.} end ;
def sections:
{sections:{section:[.]}}
| .. | .section? | enumerate | objects | del(.sections) + sectionids ;
{
"result": .id,
"entities": {
"sections": (reduce sections as $s ({};.["\($s.id)"]=$s))
}
}
Sample Run (assumes proper json data in data.json and the above filter in filter.jq)
$ jq -M -f filter.jq data.json
{
"result": 123,
"entities": {
"sections": {
"123": {
"id": 123,
"sections": [
"1",
"2",
"3"
]
},
"1": {
"id": 1,
"name": "test",
"sections": [
"125"
]
},
"2": {
"id": 2,
"name": "test2",
"sections": [
"124"
]
},
"3": {
"id": 3,
"name": "test3"
},
"125": {
"id": 125,
"name": "test125"
},
"124": {
"id": 124,
"name": "test124"
}
}
}
}
Try it online!

Model response containing array of different object types in swagger

I want to model a response object containing an array of different types of objects in swagger, something like this:
{
"table": [
{
"user" : []
},
{
"customer": []
},
{
"employee": []
}
]
}
I have tried a solution below but it wraps all the properties in a single object { [ { "user": [], "customer": [] } ] }.
responses:
200:
schema:
type: array
items:
type: object
properties:
user:
type: array
items:
$ref: '#/definitions/User'
customer:
type: array
items:
$ref: '#/definitions/Customer'
employee:
type: array
items:
$ref: '#/definitions/Employee'
That will be supported in the next release of OpenAPI spec (3.0) and here is the related discussion about this feature:
https://github.com/OAI/OpenAPI-Specification/issues/57
Here is an example (provided in the URL above):
{
"oneOf": [
{ "$ref": "Cat" },
{ "$ref": "Dog" }
]
}

How to Specify POST with JSON body in Swagger Editor

i have a POST method REST API with request body as json, which has
{
"name": "5-Star",
"vendor": "Cadbury",
"description": "More almonds with chocolate",
"price": 5,
"primaryImage": "http://cdn.shopify.com/s/files/1/0219/2362/products/Front_a8743e5a-c6a3-4042-9cb2-834332af77d5_large.jpg?v=1377892407",
"variants":
[
{ "name" : "size",
"type" : null,
"defaultValue" : "8",
"values" :[ "8","8.5"]
},
{ "name" : "color",
"type" : "COLOR",
"values" :[ "Milky White","Chocolate"]
}
],
"tags":
[ "Chocolate", "Cadbury" ]
}
I need to know how to set parameter for variants in the above json in swagger 2.0 editor, also referenced documentation and petstore sample from swagger but i cant find any clue.
Maybe this will get you started:
properties:
... // other stuff
variants:
type: array
description: variants description
items:
properties:
name:
type: string
description: the name
... // the rest

Resources