OpenAPI: mix of mandatory fields, optional fields and unspecified fields - swagger

I need to specify that my endpoint has a mandatory field, an optional field and open to any number of fields(which can be sent without validation).
For e.g. for an endpoint /user
user_id: str, mandatory
timestamp_utc: timestamp, optional
..*accept_any_extra_fields**..
So if someone sends the following json to my endpoint, the endpoint should accept it
{ "user_id": 1,
"name": "Sam",
"location": "USA"
}
but it fails if the following json is sent as it does not contain user_id.
{ "name": "Sam",
"location": "USA"
}
it should fail.
I'm new to OpenAPI/Swagger. I know I can send the extra data. But how do I describe this as documentation on OpenAPI so a person(or a program) knows that they can send any field (e.g. name, location) along with user_id

Do you use Java-Spring? I use Swagger in Annotation approach in my Spring controllers, and in java code, you can specify params that you need in this way:
#ApiOperation(value = "Get user", notes = "Get a user by the given filters")
#GetMapping("v1/users")
public UserDTO getUsers(#ApiParam(value = "User id", required = true)
#RequestParam(value = "user_id", required = true) String userId,
#ApiParam(value = "Date", required = false)
#RequestParam(value = "timestamp_utc", required = false)
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) LocalDateTime utc,
#ApiParam(value = "Some other", required = false)
#RequestParam(value = "some_other", required = false) String someOther){
return service.getUser(userId, utc, someOther);
}
The annotation #ApiOperation is to describre your endpint.
The annotation #ApiParam is to describe the param characteristics, and the attribute required is to inform that is.
Don't forget to add the swagger dependencies, here is on maven.
You also have the possibility to generate your API documentation in YAML. An example is here . Please check the endpoint for user/login.
I hope my answer will help you.

The additionalProperties keyword allows a schema to have extra properties besides those listed in the properties section.
MyModel:
type: object
required:
- user_id
properties:
user_id:
type: string
timestamp_utc:
type: string
additionalProperties: true # OpenAPI 3.0
# or
# additionalProperties: {} # OpenAPI 2.0
Actually OpenAPI schemas are open to extension by default, in the absence of the additionalProperties keyword. However, some tools consider the absence of additionalProperties as "additional properties NOT allowed", so it's best to add additionalProperties: true / additionalProperties: {} explicitly just in case.
If the extra properties are limited to a specific data type, e.g. string, use
additionalProperties:
type: string

Related

How to use ref and other fields in the request body?

My use case in the root level json there are 100 fields and out of those 100 fields 90 fields are common and the remaining 10 fields varies for different API's, I need to specify this 90 fields in a global space and on top of that I need to put the 10 different fields
SAMPLE
POST localhost:3000/api/v1/people
{
name: "", age: "", father_name: ""
//other 90 fields
}
POST localhost:3000/api/v1/student
{
//all fields of people and the below fields.
department_name:"", courses_enroled: ""
}
POST localhost:3000/api/v1/teacher
{
//all fields of people and the below fields.
yoe: "", //assume some specific fields
}
I need to define people payload in global space and in student API, I need to ref it.
How to do this in swagger.
whenever I use ref, it replaces al other fields in the same level.
You can extend existing definition in Swagger 3 and higher (not sure which version you are using). Example in yaml (not sure what you use):
definitions:
Response:
description: "Response Object"
type: object
properties:
success:
description: "If action was successful or not"
type: boolean
example: true
message:
description: "Action message"
type: string
example: "Some message"
data:
description: "Response data"
type: Any
nullable: true
ErrorResponse:
allOf:
- $ref: "#/definitions/Response"
- type: object
properties:
success:
example: false
message:
example: "Error message"
data:
example: null

How to define in swagger spec either of two properties are not null and required

I have a requirement to have two properties in the payload say property1 and propert2. Both are array type. Condition is, that either both can have values, or only one of them will be non-null. But both cannot be null at the same time.
How can I define this requirement in swagger spec, so that I can enforce schema such that both should not be null but any one of them can be null.
Valid Examples:
Ex1--> {"Property1": ["value1"], "Property2": ["value2"]}
Ex2--> {"Property2": ["value2"]}
Ex3--> {"Property1": ["value1"]}
Invalid Example:
{"Property1": [], "Property2": []}
Assuming the object can only contain these two properties (Property1 and/or Property2) and no other properties, your use case can be defined using a combination of object-level minProperties and array-level minItems:
MyObject:
type: object
minProperties: 1 # <-- requires at least one of Property1 or Property2 to be present
properties:
Property1:
type: array
items:
type: string
minItems: 1 # <-----
Property2:
type: array
items:
type: string
minItems: 1 # <-----
If the payload can also contain other properties, the "either Property1 or Property2 must be present" condition can be defined using anyOf + required. This requires OpenAPI 3.x:
# openapi: 3.x.x
MyObject:
type: object
anyOf: # <----------------
- required: [Property1]
- required: [Property2]
properties:
Property1:
type: array
items:
type: string
minItems: 1
Property2:
type: array
items:
type: string
minItems: 1
SomeOtherProperty:
...

How to modify context for child fields in graphql-ruby?

I have query like this:
query {
organizations {
id
name
itemA {
fieldA
fieldB
}
}
}
returns
"data": {
"organizations": [
{
"id": 123,
"name": "first org",
"itemA": {
"fieldA": "some value A",
"fieldB": "other value B",
}
},
{
"id": 321,
"name": "other org",
"itemA": {
"fieldA": "other value A",
"fieldB": "value B",
}
}
]
}
One user have access to multiple organizations, but with different access rights for each org.
I need to have organization.id when fieldA and fieldB are resolved to validate access.
I tried to use context.merge_scoped!(organiozation_id: org.id) in resolver for a field, that returns single org.
Looks like it do what I need, child fields received correct value in context but I'm not sure. There is no documentation for that method and for scoped_context in general.
Also, if scoped_context is what I need, how can I set it for a list of items?
UPD: sample query
query {
organizations { // I need to pass item of this list to resolver of ItemA
someModel{
otherModel {
itemA // access depened on organization`
}
}
}
}
Feature was documented in newer version:
https://graphql-ruby.org/queries/executing_queries.html#scoped-context
I'm not 100% sure I got your problem, but I think what you need should be "transparent" to GQL.
You need two things to correctly list "items" for an organization: 1. which organization and 2. who is asking:
# type organization
def itemA
object # this is 1, the organization, current node in the graph
.get_fields_accessible_by(context[:who_is_asking]) # this is requirement 2
end
As you can see, there seems not to be a reason to manipulate context at all. (Unless I missed the point completely, so feel free to amend your question to clarify).
Could you try :
context[:organisation] = object #set this value in your organisation model
access it in another model using, current[:organisation]
Additionally, you can create helper method
something like
def current_organisation
context[:current_organisation]
end
Thanks

Nested query GraphQL : Syntax error - iOS

I am working with Apollo GraphQL and have to call nested query .But while call the Query in .graphql file it showing
Syntax error : Expected Name, found {
Let me know how to call Nested query of GraphQL.
I have to call getAllproduct{....} query with the specified parameters.Here the FilterInput having the parameter as location with another pattern of query , so I don't know how to call this nested query.Anyone please help me to find out the solution.Thanks...
If an argument is an Input Object Type (as opposed to a Scalar), you can include the fields of the Input Object Type by using curly brackets.
query MyProductsQuery {
allProducts(
pageNumber: "someString"
filter: {
title: "someOtherString"
yearFrom: 1900
location: {
city: "yetAnotherString"
state: "FL"
}
}
) {
id
# other product fields
}
}
Of course, hardcoding those values in a .graphql file is not very helpful. You probably want to be able to swap those values out programatically. So here's what that same query looks like with variables:
query MyProductsQuery($pageNumber: String, $filter: FilterInput) {
allProducts(pageNumber: $pageNumber, filter: $filter) {
id
# other product fields
}
}
Your variables are passed in separately from your query and unlike your query, are not a GraphQL document. They are just JSON:
{
"pageNumber": "someString",
"filter": {
"title": "someOtherString",
"yearFrom": 1900,
"location": {
"city": "yetAnotherString",
"state": "FL"
}
}
}

Swagger is adding additional body parameter for get method

I'm using swagger akka-http wrapper, Currently for my get request swagger is adding additional body parameter in swagger spec of type string
#Path("/{id}/status")
#ApiOperation(httpMethod = "GET", response = classOf[JobStatus], value = "Returns Job status")
#ApiImplicitParams(Array(
new ApiImplicitParam(name = "id", required = true, dataType = "integer", paramType = "path", value = "Job id for which status be fetched")))
#ApiResponses(Array(
new ApiResponse(code = 200, message = "OK", response = classOf[JobStatus]),
new ApiResponse(code = 404, message = "Job not found")))
def getStatus(id: String): Route =
get {
....
I'm wondering this is because of getStatus method taking parameter "id", Do any one have any suggestion
The generated docs are based on the both the function parameters and the implicit parameters (ie the union of the 2 parameter sets).
I would suggest that you remove the ApiImplicitParam annotation and add an ApiModelProperty annotation to the id field in the function parameter list if you need to override its declared type of String.
Example use of ApiModelProperty annotation:
https://github.com/pjfanning/swagger-akka-http-sample/blob/master/src/main/scala/com/example/akka/addoption/AddOptionActor.scala

Resources