OpenAPI 3 specification of Option[] - scala

Let's say I have this case classes as part of some OAS3 specification:
case class UserData(userId: String, country: Country)
case class Country(id: String, name: String)
Then, the OAS3 specification would be something like this:
components:
schemas:
UserData:
type: object
properties:
userId:
type: string
country:
$ref: '#/components/schemas/Country'
Country:
type: object
properties:
id:
type: string
name:
type: string
My question is: If a made country as Option, how can I model this?
case class UserData(userId: String, country: Option[Country])
case class Country(id: String, name: String)
I try putting "nullable: true" but this is not valid:
components:
schemas:
UserData:
type: object
properties:
userId:
type: string
country:
nullable: true <---- NOT VALID
$ref: '#/components/schemas/Country'
Country:
type: object
properties:
id:
type: string
name:
type: string
How can I model this Option?

Mark all of the non optional parameters as required:
components:
schemas:
UserData:
required:
- userId
type: object
properties:
userId:
type: string
country:
$ref: '#/components/schemas/Country'
Country:
required:
- id
- name
type: object
properties:
id:
type: string
name:
type: string

Related

OpenApi / Swagger v3 Question around Using References by Id instead of Object

I'm trying to determine how I can set up a request in a manner that makes it easier for end users to interact with it:
so given that Pet is defined as such:
#/components/schemas/Pet
Pet:
x-swagger-router-model: io.swagger.petstore.model.Pet
required:
- name
properties:
id:
type: integer
format: int64
example: 10
name:
type: string
example: doggie
category:
$ref: '#/components/schemas/Category'
status:
type: string
description: pet status in the store
enum:
- available
- pending
- sold
type: object
ApiResponse:
properties:
code:
type: integer
format: int32
type:
type: string
message:
type: string
type: object
and Category is defined as:
#/components/schemas/Category
x-swagger-router-model: io.swagger.petstore.model.Category
properties:
id:
type: integer
format: int64
example: 1
name:
type: string
example: Dogs
xml:
name: category
type: object
and the way to add a new object is by using this POST:
paths:
/pet:
post:
tags:
- pet
summary: Add a new pet to the store
description: Add a new pet to the store
operationId: addPet
responses:
'200':
description: Successful operation
content:
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/json:
schema:
$ref: '#/components/schemas/Pet'
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
requestBody:
description: Create a new pet in the store
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Pet'
application/xml:
schema:
$ref: '#/components/schemas/Pet'
application/x-www-form-urlencoded:
schema:
$ref: '#/components/schemas/Pet'
How do i generate a POST with this format:
{
"id": 10,
"name": "doggie",
"category": 1,
"status": "available"
}
instead of this:
{
"id": 10,
"name": "doggie",
"category": {
"id": 1,
"name": "Dogs"
},
"status": "available"
}
I understand that I can set up a different schema for POST by specifying that for this type of request i would use an int for the category, but was hoping there would be a way to maintain the appropriate referencing of the pet.category to the category.
any ideas would be appreciated.
ps note that the reference for this example is directly accessible here

How to get SQL's "AND" operator behavior in mongoose

const ItemSchema = new mongoose.Schema({
categoryId: {
type: mongoose.Types.ObjectId,
required: true,
ref: 'Category'
},
companyId: {
type: mongoose.Types.ObjectId,
required: true,
ref: 'Company'
},
name: {
type: String,
required: true
}
})
const CategorySchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
displayOrder: {
type: Number,
required: true,
},
description: {
type: String
}
});
const companySchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true
},
address: {
address: String,
city: String,
state: String,
country: {
type: mongoose.Schema.Types.ObjectId,
ref: 'countrycodes'
},
pincode: String,
}
});
I have this above schema and trying to get the items which has company name="KFC" and category name="food"
Along with the items I want to populate the company and category objects.
const itemList = await Item.find().populate(
{
path: 'companyId',
match: { name: 'KFC'},
select: '_id name'
}).populate(
{
path: 'categoryId',
match: { name: 'food'},
select: '_id name'
}
).lean();
I tried using populate as shown below but this returns items which do not have category name="food" but has comp
name="KFC"
How can I get the items which has company name="KFC" and category name="food" and ignore the ones which do not satisfy both company and category condition.
Also, Is populate() the right way to get the results I want?

How to define an unwrapped response in OpenAPI?

I have this component:
components:
schemas:
book:
type: object
required:
- id
properties:
id:
type: string
title:
type: string
author:
type: string
Is there a way to define a response object that includes the book attributes using this component? The response is this:
{
"id": "xxxxx",
"title": "This is title",
"author": "John"
}
I tried like this:
responses:
200-response:
description: HTTP 200 response
content:
application/json:
schema:
type: object
properties:
book:
$ref: '#/components/schemas/book'
but it has the parent object of book instead of the attributes immediately.
You're almost there. Just put the schema $ref directly under schema.
responses:
200-response:
description: HTTP 200 response
content:
application/json:
schema:
$ref: '#/components/schemas/book'

MongoDB: How to find the relationships between collections in database

I have a collection of user which has id, firstName, lastName. id field of user collection has been used in another collection.
Is there any way to find all collection which used user id?
user schema:
let userSchema = new mongoose.Schema({
firstName: {
type: String,
trim: true,
required: true
},
lastName: {
type: String,
trim: true,
required: true
}
},
{
timestamps: true,
usePushEach: true
});
training schema:
var trainingSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
name: {type: String, required: true},
institution: {
instituteName: {type: String, required: true},
type: {type: String, required: true},
address: {
country: String,
state: String,
city: String
}
},
startDate: Date,
endDate: Date,
achievements: String,
createdAt: Date,
updatedAt: Date,
endorsers: [{
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
profilePic: {
container: {type: String,default: null},
name: { type: String, default: null }
},
currentPosition: {type: String,default: ""},
currentWorkingCompany: {type: String,default: ""}
}],
});
In above schema userId come from user collection
Note: similar to this which is available in MYSQL:
SELECT
ke.referenced_table_name 'parent table',
ke.referenced_column_name 'parent column',
ke.table_name 'child table',
ke.column_name 'child column',
ke.constraint_name
FROM
information_schema.KEY_COLUMN_USAGE ke
WHERE
ke.referenced_table_name IS NOT NULL
AND table_schema = 'your_db_name'
ORDER BY ke.referenced_table_name;
Source: here
You probably need MySQL function named join. In MongoDB it is named $lookup and it is part of aggregate function.

Specify an array as a parameter with Swagger

How do I specify an array as a parameter? For instance, post to /persons can be given strings username, firstname, and lastname, and array myArray.
paths:
/persons:
post:
parameters:
- name: person_what_is_the_purpose_of_this
in: body
description: The person to create.
schema:
required:
- username
properties:
firstName:
type: string
lastName:
type: string
username:
type: string
myArray:
type: array
items:
properties:
myArrayElement:
type: string
responses:
200:
description: A list of Person
schema:
type: array
items:
required:
- username
properties:
firstName:
type: string
lastName:
type: string
username:
type: string
swagger: "2.0"
info:
version: "1.0.0"
title: Swagger Petstore
host: petstore.swagger.io
basePath: /v2
schemes:
- http
paths:
/pets/findByStatus:
get:
parameters:
- in: query
name: status
type: array
items:
type: string
responses:
"200":
description: successful operation
schema:
type: array
items:
type: object
required:
- name
- photoUrls
properties:
id:
type: integer
format: int64
category:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
name:
type: string
example: doggie
photoUrls:
type: array
items:
type: string
tags:
type: array
items:
type: object
properties:
id:
type: integer
format: int64
name:
type: string
"400":
description: Invalid status value
You need to specify collectionFormat: multi
For your array it would look like this, be sure to put it on the same level as the type:
myArray:
type: array
collectionFormat: multi
Documentation about arrays