I am currently working on project using Symfony 4.3.4 and API platform v2.3.6.
I am facing 1 issue right now. Let’s say I send a GET request to an enpoint with a query string parameter called products because I send 1 or more product IDs.
I want to get the value of the products parameter in my controller as a PHP array.
So my request is
GET /my/endpoint?products[]=8f391c60-5467-4bf0-917f-e2151337fa7e&products[]=ddaa94e1-af79-4abf-9dfc-a28dd8077f45
In the controller I perform a dump:
dump($request->query->get("products"));
Then I get:
array:2 [
0 => "8f391c60-5467-4bf0-917f-e2151337fa7e"
1 => "ddaa94e1-af79-4abf-9dfc-a28dd8077f45"
]
As you can see the way I pass my product IDs like an array in the query string, I can retrieve the products parameter as a PHP array.
My concern here, is the swagger documentation.
Using this configuration in YAML:
collectionOperations:
operation_name:
method: get
path: /my/endpoint
controller: App\Controller\MyEndpointController
swagger_context:
summary: My summary
description:
My endpoint description
responses:
parameters:
-
in: query
name: products
description: "The products IDs parameter"
schema:
type: array
items:
type: "string"
example: "019fcd9b-beea-4791-8a59-d4e2d02427d6"
In the API documentation page when I choose Try it out I have to fill in all the parameters value included products. The problem is that products parameter appears as a text input.
If I remove the schema key in the yaml configuration of the parameter and I put type: array and items keys directly at the same level as in, name and description:
parameters:
-
in: query
name: products
description: "The products IDs parameter"
type: array
items:
type: "string"
example: "019fcd9b-beea-4791-8a59-d4e2d02427d6"
Then the products parameter appears with a button Add item. Each time I click on this button, I can fill a product ID to pass and that is fine. The problem is that when I click on Execute (still in the API documentation page) I have an error because API platform does not send the request with products parameter as a true array but as a string containing all product IDs separated by ,:
GET /my/endpoint?products=8f391c60-5467-4bf0-917f-e2151337fa7e,ddaa94e1-af79-4abf-9dfc-a28dd8077f45
and this is what I want:
GET /my/endpoint?products[]=8f391c60-5467-4bf0-917f-e2151337fa7e&products[]=ddaa94e1-af79-4abf-9dfc-a28dd8077f45
any idea about the way to achieve this with API platform?
The query parameter needs to be named products[] (with square brackets) and have the collectionFormat: multi attribute:
parameters:
- in: query
name: products[]
type: array
items:
type: string
format: uuid
collectionFormat: multi
# (Optional) Array example to display in Swagger UI
x-example:
- 8f391c60-5467-4bf0-917f-e2151337fa7e
- ddaa94e1-af79-4abf-9dfc-a28dd8077f45
Note that query parameters in OpenAPI 2.0 do not support the example keyword, but some tools (such as Swagger UI) support the x-example extension to specify the example values for query parameters.
Related
I have some schema definitions created with fastify as in below, where I have used 'title' to give meaningful name of my models.
fastify.addSchema({
$id: 'persistence-query-params',
title: "PersistenceQueryParams", // Here
type: 'object',
description: 'Persistence Service GET API URL query specification. Applicable for GET API only.',
properties: {
...........
},
});
However when I am looking at the json generated from the swagger (I am using fastify-swagger: 4.8.4 and fastify: 3.20.1), I am seeing this
def-7: ## Here
title: PersistenceQueryParams
type: object
description: >-
Persistence Service GET API URL query specification. Applicable for GET
API only.
properties:
This is coming up in the OpenAPI 2.0 https://editor.swagger.io/, when loading the json generated out of that schema.
I have tried out adding the name field also:
name: "PersistenceQueryParams",
However no luck.
How can I create meaningful names, instead of def-0, def-1 etc in OpenAPI 2.0?
Thanks,
Pradip
I have an OpenAPI 3.0.1 file and conforming to the standard it contains some examples responses for endpoints. Now since some of the parameters in the response are set to be nullable there are some examples which look as follows:
examples:
account_not_verified:
value:
eamil: 'test#example.com'
verification: '0'
name: null
Since the name parameters is set up like this:
name:
type: string
nullable: true
I would assume that having a null value in the example response is valid by the open api standard. When I put this into the Swagger Editor is does not show any errors or warnings. But as soon as I include the OpenAPI file into my sam template to be used to configure an HTTP API Gateway like so:
ApiGateway:
Type: AWS::Serverless::HttpApi
Properties:
StageName: !Ref Stage
FailOnWarnings: true
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: ./oapi.yml
Cloud formation gives me the following error:
[/Resources/ApiGateway/Type/Body/paths/***/content/application/json/examples/ch_account_not_verified/value/name] 'null' values are not allowed in templates
Is there any way to allow this null value to exist in the example response or do I have to use some different method to indicate the null value in the example?
So with some trial and error, I was able to define it to allow strings and nulls, at least for a SAM template RequestBody. I am assuming API gateway uses JSON validation under the sheets, so if you define this in JSONSchema , for something like AWS power-tools validation, for example:
"properties": {
"spouse_first_name": {
"$id": "#/properties/spouse_first_name",
"type": ["string", "null"],
"title": "The spouse_first_name",
"maxLength": 100
}
}
Then the equivalent syntax in SAM template YAML would be:
MyRequestModel:
type: object
properties:
spouse_first_name:
type: string, null
maxLength: 100
I just tested this and it seems to allow both strings and nulls.
In the case of body validation, Don't forget to add 'ValidateBody: true' in your SAM template to force API gateway to validate your payload:
RequestModel:
Model: MyRequestModel
ValidateBody: true
I realize this is not an apples to apples answer, but the take away is that you should be able to define it in comma separated values in YAML
Today i got into swagger and swagger-ui to create the documentation of our API.
We are using AWS API Gateway with a Lambda function, since AWS is comming with an in-built option for documentation we are going with it.
Sadly, I am pretty limited with this option or I am doing it wrong.
As an example
responses:
'200':
description: 200 response
schema:
$ref: '#/definitions/Empty'
I can´t create an alternative schema, nor im able to edit the existing /Empty schema.
Is there a solution for my problem?
For example
... to not use an schema and just write the whole response in there?
... to show me how to create an alternative schema?
EDIT
For me it seems like an AWS problem, not my swagger file in generall. If someone reads over this i added more informations.
It doesnt matter if i use "create Documetation Part" --> Type = Response (Body) or i go to Ressources --> Method which i want to set the Response (Body) --> Method Response and set the Respone Body to an Modell.
My Modell looks like this
{
{
"$schema": "http://json-schema.org/draft-04/schema#",
"description" : "Example Promotion",
"title" : "Promotion",
"type" : "object",
"properties" : {
"Status" : { "type" : "string"}
}
}
}
It gives me no error, but if i go to "Publish Documentation" it seems to no put the Respone (Body) i set into the swagger.json on the Method Response part, nor on the Defenitions at the end of the file and set the schema path right.
I found it easier to not use $ref when I was starting out. After you have the knack how to write requests or response definitions, you can easily transition to referencing schemas using $ref.
What comes after schema statement? That depends on what you expect to be returned -- text, an array, a JSON object, or an array of JSON objects, etc. Typically it's the later two. So here is an example of each.
schema:
type: object
description: This is a JSON object
properties:
fullName:
type: string
age:
type: number
which defines: { fullName: "Jane Smith", age: 30 }
schema:
type: array
description: This is an array of JSON object
items:
type: object
properties:
carMake:
type: string
carModel:
type: string
which defines: [{ carMake: "Ford", carModel: "Mustang" } ... ]
Clone github's swagger-ui onto your computer and run it as a local server. Or you have free use of the SwaggerHub if you don't mind the API definition to be public (or, after a trial period, pay for your APIs to be private).
The specification has changed over the years, so its important to know whether you are dealing with swagger v2 or openapi v3. www.swagger.io has a good multi-page tutorial. And you can find several public API examples at the SwaggerHub website. I do not work for Smartbear, the originators of both the original swagger spec and swaggerhub tooling, but I've found them to be very helpful in the past. Some of their staff monitor this website and answer questions.
Good luck!
Learning about REST APIs and am following https://apihandyman.io/writing-openapi-swagger-specification-tutorial-part-2-the-basics/.
The API can receive two parameters: username and bla, but only username is required by using the required keyword. This makes sense to me.
The API will return firstname, lastname, and username, but only username is required by using the required keyword. This does not make sense to me. Does the lack of the required keyword indicate that the other two might sometimes not be required? What influences whether they are or are not?
paths:
/persons/{username}:
get:
summary: Gets a person
description: Returns a single person for its username.
parameters:
- name: username
in: path
required: true
description: The person's username
type: string
- name: bla
in: query
description: bla bla bla
type: string
responses:
200:
description: A Person
schema:
required:
- username
properties:
firstName:
type: string
lastName:
type: string
username:
type: string
404:
description: The Person does not exists.
Your interpretation is correct. If a property of a response object is listed in the required property list, is must be present in the response object for it to be valid, quite similar to the required field in a parameter object. Whether a non-required property is included in the response or not is up to the business logic of your application to decide.
Some more information with pointers to the relevant parts of the specification below:
The semantics of the required property list of a response object is defined as part of the Schema Object section of the OpenAPI specification. There it says that the schema object "is based on the JSON Schema Specification Draft 4 and uses a predefined subset of it".
In the corresponding section on the required validation keyword of the JSON Schema Validation specification its semantics is defined as follows:
5.4.3. required
5.4.3.1. Valid values
The value of this keyword MUST be an array. This array MUST have at
least one element. Elements of this array MUST be strings, and MUST be
unique.
5.4.3.2. Conditions for successful validation
An object instance is valid against this keyword if its property set
contains all elements in this keyword's array value.
You'll find further examples of how the required keyword can be used in the examples section of the JSON Schema specification or Part 5, Section 2.2 of the tutorial you're following.
Facebook API supports choosing nested object's selected fields in the response in following manner:
GET graph.facebook.com
/me?
fields=albums{name, photos{name, picture}}
Reference: https://developers.facebook.com/docs/graph-api/using-graph-api#reading - Section: Making Nested Requests
When using Koala Ruby Gem to send request to Facebook API what is the syntax for specifying nested fields?
On this wiki page https://github.com/arsduo/koala/wiki/Graph-API#getting-public-data following example is given:
client = Koala::Facebook::API.new(oauth_token)
client.get_connection('someuser', 'posts',
{limit: #options[:max_items],
fields: ['message', 'id', 'from', 'type',
'picture', 'link', 'created_time', 'updated_time'
]})
So to add the fields supported by a Facebook API end-point we pass in a hash containing fields as the key and an array of supported fields name like ['message', 'id', 'from'].
If any of the field represents a object which has its own properties, like in case of a Page's Rating endpoint which returns a list of OpenGraphRating nodes and an OpenGraphRating object has following property open_graph_story which is an object, then how do we specify nested properties when using Koala's fields syntax?
When using the endpoint directly it goes like:
page-id/ratings?fields=created_time,has_rating,has_review,open_graph_story{id},rating,review_text,reviewer
I also got stuck at the same thing.
I found out that the koala takes the fields as an array of strings and then make query string out of it.So for nested properties we can directly write as
client.get_connection('someuser', 'posts',
{limit: #options[:max_items],
fields: ['albums{name, photos{name, picture}}','comments.summary(true).limit(100){likes.summary(true),from,message,created_time,comments.summary(true).limit(100){likes.summary(true),from,message,created_time}}', 'id', 'from', 'type',
'link', 'created_time', 'updated_time'
]})