Is there any annotation or way to display mutually exclusive field in API model (JSON) correctly in swagger ?
eg. If I have following API model and I want to show field A and B are mutually exclusive e.g. Java class say AtoZ has following structure
class AtoZ {
String A;
String B;
#ApiModelProperty(value ="This is field C", required = true)
String C;
}
Let say field C is required as annotated above but field A and B are mutually exclusive i.e. only one of field is required/can exist. If both A and B are annotated as Optional (i.e. required =false) that will not enforce mutually exclusive constraint.
Wondering if there is any appropriate annotation in swagger which allow documenting this kind of structure in Swagger UI ?
Related
Recently, I am migrating Swagger from SpringFox to SpringDoc, and meeting an issue of handling object parameters.
For example, the object contains 3 attributes: A, B and C. In Swagger I can set A B C with values: a, b and c. I am wondering can I in some way use "a:b:c" as a path parameter.
I have checked the parameters serialization here: https://swagger.io/docs/specification/serialization/ But there is no styling like this: "a:b:c"
I have such function in my data source:
func getAllFood(by type: String) -> [UserFoodInformation] {
var findedFood = [UserFoodInformation]()
findedFood.append(contentsOf: baseUserFoodDataSource.getAllFood(by: type))
let predicate = NSPredicate(format: "foodType == %#", type)
let resultOfSearching = dataBase.objects(AddedUserFood.self).filter(predicate).sorted(byKeyPath: "name")
for searchedFood in resultOfSearching {
findedFood.append(searchedFood)
}
return findedFood
}
When I try to query with string that consist whitespace, I have no result, but if I query with simple one-word parameter, everything goes fine. Why is that? Can I have a string field in Realm that consists multiple words?
The predicate you're using is looking for objects whose foodType property is equal to the type string that is passed in. Only those objects whose property is exactly equal to that string will match. If you want to perform some other form of matching you'll need to use something other than the equality operator. BEGINSWITH, CONTAINS, ENDSWITH and LIKE are the comparison operators that Realm supports on string fields.
Can I have a string field in Realm that consists multiple words?
String fields can contain any string values. The supported comparison operators don't have the concept of a "word", though, so if you want to do filtering using that concept you'll likely need to do further work on your part. Depending on your use case, I can see a couple of ways to go about it:
Use CONTAINS to find any objects whose foodType properties contains the given type string.
Parse the string into structured data that you store in your model. For instance, it may make sense to store a List<FoodType> rather than a String for the foodType property.
There are likely other options, but they depend on details of what it is you're trying to achieve that you've not shared.
I have one domain class design issue regarding validation for the following domain classes:
Class Course {
String name // computers,maths,economics,zoology etc...
}
class Component{
String name //ex: C1,C2,C3
boolean type // 0 means internal , 1 means external
}
Class CourseComponent{
Course course
Component component
Integer MaxMarks
...
}
There client requirement is when creating CourseComponents for the particular Course .. total maxMarks should be equals to hundred. So
for instance: for Maths Course,component distribution like
1.Maths C1 15
2.Maths C2 15
3.Maths C3 70
The total marks should be equals 100.
How would I go about writing a constraint that examines multiple records or how do I need to change my domain classes?
If I correctly understood the requirement then CourseComponent should hold a collection of Component.
In this case I would not add a maxMarks attribute to the CourseComponent class since it may be computed easily and available through an accessor method. Therefore I would move this attribute to the Component class for storing the number of an individual Component for a given Course (or CourseComponent).
Next I would add a validation on the total maxMarks when adding Component instances to the CourseComponent.
But another question is do you really need a CourseComponent class?
You might have a Course class that holds related Component instances as a collection attribute.
How to design REST url for resource collection, which filters resource by attribute not equal to a given value?
For example, to get the students in 8th grade, we use
GET /students?grade=8
How to do the same, if we need to get the students not in 8th grade? And how to design for less than (<) , greater than (>) etc ?
What I am thinking of doing is including the operator as part of the argument, delimited from the value. I would also define non-symbolic operators to avoid the need for ugly URL-encoding or confusion with the equals sign after the parameter name. For your example, this would be something like this for students not in grade 8:
GET /students?grade=neq|8
Students in grades > 8 would be:
GET /students?grade=gt|8
Students between grades 8 and 10 (inclusive):
GET /students?grade=gte|8,lte|10
This approach can be extended to other filterable fields without the need to add additional parameters to modify the way each field is filtered.
Stripe has one of the most respected APIs.
They use a separate parameter for each operator separated with a dot.
For example, to search on created date:
/charges?created.gt=
/charges?created.gte=
/charges?created.lt=
/charges?created.lte=
In your case you could do something like:
/students?grade.gt=8&grade.lt=8
Or even add another operator for not:
/students?grade.not=8
One option would be to add an additional query parameter such as gradeOperator in which you could pass the operator to be used when comparing the value against the grade parameter. E.g.,
GET /students?grade=8&gradeOperator=!%3D
!%3D is the URL-encoded form of !=, so your REST API would de-encode the operator and interpret this as grade != 8.
Another approach would be to pass the value and operator in the HTTP request body. Something like this would potentially work (with the body provided in JSON as an example):
GET /students
Content-Type: application/json
{ "grade": {"value": 8, "operator": "!=" } }
That could be nice since you wouldn't have to repeat the word 'grade' in gradeOperator, the operator is simply nested inside a JSON object as the value of grade.
In either solution, you could potentially define any number of operators, including <, >, >=, <=, etc. Just be sure to properly sanitize any input operators your API receives, especially if used in a DB query, to avoid things like SQL injection attacks.
I have the following scenario,
Domain class A which hasMany B's
Domain class B which hasMany C's and belongsTo A
Domain class C which belongsTo B
Class E {
A a
B b
C c
}
Class C {
String name
}
I want to query E values i.e get a list of some E property eg in this case c.name based on values selected by a user in a select box, i.e user selects A and B from multiple select boxes and based on this criteria, a list of names is obtained.
in other words i want to find all names in c which satisfy condition set by a and b
have tried to figure out the GORM query to no avail.
thanks
I solved this by using raw SQL joins. Not really certain if this was the best way but it worked for me.
I got the parameters from A and B, ie
def fromA = params.someCriteriaValueInA
def fromB = params.someCriteriaValueInB
Please note that these are fetched from a gsp. Also, fromB values would be loaded based on fromA values, using chained selects.
In the grails controller/service ...
def db = new Sql(dataSource)
def result = db.rows("your sql to go here")
Then you can do whatever you want with the results, for example manipulate it in a template
render(template: "myResults", model:[result :result])
Dont forget to inject the dataSource bean in your controller/service, and also doing the necessary import
import groovy.sql.Sql
Please note that this involved traversing many domain class instances, and for those who like raw SQL this would seem easier.Would appreciate a different approach, maybe using GORM's criteria.