How to exclude a property from a referenced schema? - openapi

I have an endpoint to create an address and one to update it. Describing this in an OpenAPI spec I'd like to use a component for the address so that I don't have to specify the address twice. Now the problem is, that the address object used for updating should include a property "id", but the one used for creating doesn't.
So basically, I'm looking for a way to describe the full address (incl. the id property) in the components section and then reference to the create endpoint, but excluding the "id" property there.

You can extend another type using the allOf keyword, as documented here
In the example below, creationType has only a name property, but updateType has all the properties of creationType as well as an id property.
Example:
components:
schemas:
creationType:
type: object
properties:
name:
type: string
updateType:
allOf:
- $ref: '#/components/schemas/creationType'
- type: object
required:
- id
properties:
id:
type: string

Related

Query string parameter in swagger documentation not sent as array in request

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.

openapi3: how to specify that an object schema should be a schema itself?

I want a field in a PUT body that is itself supposed to be a jsonschema. How do I formally specify this rather than putting that info in a description?
type: object
description: "..."
properties:
foo:
type: integer
create_schema:
type: object
description: >
jsonschema (following http://json-schema.org/draft-07/schema) of the CREATE payload...
OpenAPI doesn't like the schema keyword in a definition here

Can OpenAPI schema names have "/" in them?

I am consuming an API that uses string like "foo/bar" to identify (discriminate) JSON objects.
A $ref like $ref: '#/components/schemas/foo/bar' gives me errors.
Is this naming supported? I want to use leverage these properties provided by the API in order to use discrimination to pick the most appropriate component schema.
I am using OpenAPI 3.0.1.
No.
OpenAPI 3.0 component names (including schema names) can only contain these characters:
a-z A-Z 0-9 - . _
(Source)
However, there are no restrictions on property names in schemas, so / can be used in property names:
components:
schemas:
MySchema:
type: object
properties:
foo/bar: # <-----
type: string

Should a REST API parameter ever influence which other parameters are required?

For instance, I can create a vehicle, and must give it a type which can be "automobile" or "airplane". Automobiles require a tire size parameter and airplanes require a wingspan parameter. Similar question regarding whether a REST API parameter should ever influence which properties are required in the response.
/vehicles:
post:
summary: Creates a vehicle
description: Adds a new vehicle of given type.
parameters:
- name: vehicle (what is the purpose of this????)
in: body
description: The vehicle to create.
schema:
required:
- type
- speed
- color
properties:
type:
type: string
speed:
type: interger
color:
type: string
wingspan:
type: string
tiresize:
type: string
responses:
204:
description: Vehicle succesfully created.
400:
description: Vehicle couldn't have been created.
While this happens in practice, it is best avoided as it makes it difficult to document your API. This is particularly true if you are using a documentation technology such as Swagger which does not allow these "conditionally required" parameters. By adding them, you are actually adding extra semantics to your API which are not documented in the Swagger docs.
A better approach is, instead of having a "type" parameter of different vehicle types, just use a separate URL for each type. This will allow you to properly document the required/optional parameters for each vehicle type.
/vehicles/automobile:
post:
parameters:
schema:
required:
- tyresize
properties:
tyresize:
type: string
/vehicles/airplane:
post:
parameters:
schema:
required:
- wingspan
properties:
wingspan:
type: string

What does it mean for a REST API to have a `required` response property?

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.