How to have two raml properties mutually exclusive? - raml-1.0

I have a type in raml1.0 with 4 properties and I need to implement this case:
Two properties out of the four exist only exclusively, so if one of them exists the other should not exist and if they both occur a propper error message is thrown to the user.
For example:
types:
TypeOne:
description: "Need the first two properties exist only mutually exclusively"
type: object
additionalProperties: false
properties:
Prop1:
description: "This is the first property"
type: string
required: true
Prop2:
description: "This should not exist if Prop1 exist"
type: String
required: true (only if Prop1 does not exist)
Prop3:
description: "This is optional if Prop1 exists"
type: string
required: false
Prop4:
description: "This is optional if Prop2 exists"
type: string
required: false
Any help is highly appreciated. BTW, each of these types is a complex object. I only simplified it here just for presentation.

Try this:
types:
Base:
properties:
Prop3:
description: "This is optional if Prop1 exists"
type: string
required: false
Prop4:
description: "This is optional if Prop2 exists"
type: string
required: false
TypeOne:
type: Base
additionalProperties: false
properties:
Prop1:
description: "This is the first property"
type: string
required: true
TypeTwo:
type: Base
additionalProperties: false
properties:
Prop2:
description: "This is the first property"
type: string
required: true
MainType:
type: TypeOne | TypeTwo
The documentation for union types can be found here: https://github.com/raml-org/raml-spec/blob/master/versions/raml-10/raml-10.md/#union-type

Related

mapping Swift Set of struct objects to kotlin Set of data classes with Kotlin Multiplatform Mobile

For example, I've got this simple business code in kotlin:
class ProjectItemFacade(
val projects: Set<ProjectEntity>
) {
fun sortedProjects(): List<ProjectEntity> {
return projects.toList().sortedBy { it.name }
}
}
data class ProjectEntity(
val id: String,
val name: String,
val description: String
)
I try to call it from Swift like that:
struct ProjectItem: Identifiable, Codable, Hashable {
var id = UUID().uuidString
let name: String
let description: String
}
let projects: Set = [
ProjectItem(name: "Zero Project", description: "test1"),
ProjectItem(name: "First Project", description: "test2"),
ProjectItem(name: "Third Project", description: "test3"),
]
let sortedProjects = ProjectItemFacade(projects: projects).sortedProjects()
but it gives me an error:
Cannot convert value of type 'Set<ProjectItem>' to expected argument type 'Set<ProjectEntity>'
Cannot use instance member 'projects' within property initializer; property initializers run before 'self' is available
It seems like there is a problem with mapping Swift struct to kotlin data class. How to solve it?
EDIT
After renaming the kotlin class to the same as in swift it returns first error like that:
Cannot convert value of type 'Swift.Set<iosApp.ProjectItem>' to expected argument type 'Swift.Set<shared.ProjectItem>'
As #Sweeper said in comment, I should use kotlin class in my swift code. I decided to map my array like that:
import Foundation
import shared
struct ProjectItem: Identifiable, Codable, Hashable {
var id = UUID().uuidString
let name: String
let description: String
func toEntity() -> ProjectEntity {
ProjectEntity(id: id, name: name, description: description)
}
static func fromEntity(_ entity: ProjectEntity) -> ProjectItem {
ProjectItem(id: entity.id, name: entity.name, description: entity.description_)
}
}
Note that I use entity.description_ because it seems like description property call the data class toString() method.
let projects: Set = Set(
[
ProjectItem(name: "Zero Project", description: "test1"),
ProjectItem(name: "First Project", description: "test2"),
ProjectItem(name: "Third Project", description: "test3"),
]
.map { $0.toEntity() }
)
var sortedProjects: Array<ProjectEntity> {
get {
return ProjectItemFacade(projects: projects)
.sortedProjects()
}
}
Computed get solved the second error.

OpenAPI specification for request body containing class object [duplicate]

I'm having a hard time trying to figure out how I can nest models in OpenAPI 2.0.
Currently I have:
SomeModel:
properties:
prop1:
type: string
prop2:
type: integer
prop3:
type:
$ref: OtherModel
OtherModel:
properties:
otherProp:
type: string
I have tried many other ways:
prop3:
$ref: OtherModel
# or
prop3:
schema:
$ref: OtherModel
# or
prop3:
type:
schema:
$ref: OtherModel
None of the above seem to work.
However, with arrays works just fine:
prop3:
type: array
items:
$ref: OtherModel
The correct way to model it in OpenAPI 2.0 would be:
swagger: '2.0'
...
definitions:
SomeModel:
type: object
properties:
prop1:
type: string
prop2:
type: integer
prop3:
$ref: '#/definitions/OtherModel' # <-----
OtherModel:
type: object
properties:
otherProp:
type: string
If you use OpenAPI 3.0, models live in components/schemas instead of definitions:
openapi: 3.0.1
...
components:
schemas:
SomeModel:
type: object
properties:
prop1:
type: string
prop2:
type: integer
prop3:
$ref: '#/components/schemas/OtherModel' # <-----
OtherModel:
type: object
properties:
otherProp:
type: string
Remember to add type: object to your object schemas because the type is not inferred from other keywords.
Here's another trick that works. This solution applies to OpenAPI 3 – the latest version of the OpenAPI Specification as the point of answering this question.
Here's how:
Say, I have a User model with a State enum. I defined the State enum in a different schema and then referenced it in the User schema.
components:
schemas:
User:
type: object
properties:
id:
type: integer
format: int64
first_name:
type: string
last_name:
type: string
password:
type: string
format: password
state:
$ref: '#/components/schemas/State'
State:
type: string
description: List of States
enum:
- State 1
- State 2
- State 3
- State 4
- State 5
Note that the enums were represented as arrays here, if you would love to represent them as hashes, check out this solution on Representing enum property in hash.
That's all.
I hope this helps

Can't create type with ‘id: ID! #unique’

I just setup the advanced boilerplate with the init command and added the following to datamodel.graphql
type Spot {
id: ID! #unique
createdAt: DateTime!
updatedAt: DateTime!
lat: String!
long: String!
name: String!
fishes: [Species!]!
}
type Species {
id: ID! #unique
createdAt: DateTime!
updatedAt: DateTime!
name: String!
spots: [Spot!]!
}
When I try to do prisma deploy the public demo never starts up (500 error). As soon as I remove id: ID! #unique from type Species type it starts working. I tried doing prisma reset with the same issue. When I do prisma seed -r I get the following error message, note that seed.graphql just contains the boilerplate code.
ERROR: All fields within 'Query' type should have unique names! Non-unique fields: 'species'.
{
"errors": [
{
"message": "All fields within 'Query' type should have unique names! Non-unique fields: 'species'.",
"requestId": "us1:api:cjhobke57sxok0b62n6f96ez4"
}
],
"status": 500
}
Although I was unable to figure it out exactly, if I change out the word "Species" for any other word it works. My guess is that it does not know how to properly pluralize "Species".

"Checkbox"/option type MongoDB schema design

I am looking to implement some type of checkbox functionality for settings on an account, e.g.
option:
value1: true
value2: false
value 3: false
My first thought was to have an array key named option and then have an array of Strings from an enum, like so:
key: { type: [String], required: true, enum: [
'value1', 'value2'
]}
and then I can check to see what options the users has in the array vs. the possible enum values...
But maybe I should do something like this;
key: {
value1: { type: Boolean, required: true, default: true },
value2: { type: Boolean, required: true, default: true }
}
I want this to be super customizable and flexible going forward, so I was wondering if anyone had any suggestions?
The second option is better. Much more easy to perform queries.

Extra argument in call when try to call convenience init, Swift

I have simple class:
class WmAttendee{
var mEmail:String!
var mName:String!
var mType:Int!
var mStatus:String = "0"
var mRelationShip:String!
init( email:String, name:String, type:Int) {
self.mEmail = email
self.mName = name
self.mType = type
}
convenience init( email:String, name:String, type:Int, status:String, relationShip:String) {
self.init(email: email, name: name, type: type)
self.mStatus = status
self.mRelationShip = relationShip
}
}
When I try to test 2nd constructor with 5 parameters, I get: Extra argument 'status' in call
var att1 = WmAttendee(email: "myMail", name: "SomeName", type: 1); // OK
var att2 = WmAttendee(email: "mail2", name: "name2", type: 3, status: "2", relationShip: 3)
// ERROR Extra argument 'status' in call
Why? Do I miss something?
Thanks,
Based on your method signature:
convenience init( email:String, name:String, type:Int, status:String, relationShip:String)
relationshipStatus should be a String and not an Int:
var att2 = WmAttendee(email: "mail2", name: "name2", type: 3, status: "2", relationShip: "3")
Since you're not passing the correct type for relationshipStatus, the compiler can't match the method signature for your convenience init and falls back the the default init (the closest match it can find) which triggers the Extra argument error.
Your are passing a parameter of the wrong type to your function. 'RelationShip' must be of type String, but you are passing an Integer. Yes, the compiler error is misleading, but then again swift is still in beta.