Common techniques
Annotation placement
You shouldn't place all annotations inside one big block, but scatter them throughout your codebase as close to the relevant source code as appropriate.
swagger-php
will scan your project and merge all meta-data into one @OA\OpenApi
annotation.
WARNING
As of swagger-php
v4 all annotations or attributes must be associated with a structural element (class
, method
, parameter
or enum
)
Context awareness
swagger-php
looks at the context of the annotation and will augment it with things like property name
, data type
(doctype and native type hints) as well as a couple other things.
This means in a lot of cases it is not necessary to explicitly document all details.
Example
Results in
openapi: 3.0.0
components:
schemas:
Product:
properties:
name:
description: "The product name"
type: string
type: object
As if you'd written
Response media type
The @OA\MediaType
is used to describe the content:
But because most API requests and responses are JSON, the @OA\JsonContent
allows you to simplify this by writing:
During processing the @OA\JsonContent
unfolds to @OA\MediaType( mediaType="application/json", @OA\Schema(...)
and will generate the same output.
Using references - $ref
It's quite common that endpoints have some overlap in either their request or response data. To keep things DRY (Don't Repeat Yourself) the specification allows reusing components using $ref
's
Results in:
openapi: 3.0.0
components:
schemas:
product_id:
description: "The unique identifier of a product in our catalog"
type: integer
format: int64
This doesn't do anything by itself, but now you can reference this fragment by its path in the document tree #/components/schemas/product_id
Examples
There are more uses cases on how to use refs in the using-refs example.
Array parameters in query
Depending on style-values @OA\Parameter(in="query", name="param", ...)
might create urls like this: path?param=123¶m=abc
which do not work when reading the param values in PHP.
The solution is to change the name param
into param[]
which will create path?param[]=123¶m[]=abc
and results in a PHP array.
Vendor extensions
The specification allows for custom properties as long as they start with "x-". Therefore, all swagger-php annotations have an x
property which accepts an array (map) and will unfold into "x-" properties.
Results in:
openapi: 3.0.0
info:
title: Example
version: 1
x-some-name: a-value
x-another: 2
x-complex-type:
supported:
- version: "1.0"
level: baseapi
- version: "2.1"
level: fullapi
Enums
PHP 8.1 enums are supported in two main use cases.
Enum cases as value
Enum cases can be used as value in an enum
list just like a string
, integer
or any other primitive type.
Basic enum:
Results in:
openapi: 3.0.0
components:
schemas:
Model:
properties:
someSuits:
type: array
enum:
- Hearts
- Diamonds
type: object
Backed enums
If the enum is a backed enum, the case backing value is used instead of the name.
Enum schemas
The simples way of using enums is to annotate them as Schema
. This allows you to reference them like any other schema in your spec.
Results in:
openapi: 3.0.0
components:
schemas:
Colour:
type: string
enum:
- GREEN
- BLUE
- RED
Product:
properties:
colour:
$ref: '#/components/schemas/Colour'
type: object
Backed enums
For backed enums there exist two rules that determine whether the name or backing value is used:
- If no schema type is given, the enum name is used.
- If a schema type is given, and it matches the backing type, the enum backing value is used.
Using the name of a backed enum:
Results in:
openapi: 3.0.0
components:
schemas:
Colour:
type: string
enum:
- GREEN
- BLUE
- RED
Product:
properties:
colour:
$ref: '#/components/schemas/Colour'
type: object
Using the backing value:
Results in:
openapi: 3.0.0
components:
schemas:
Colour:
type: integer
enum:
- 1
- 2
- 3
Product:
properties:
colour:
$ref: '#/components/schemas/Colour'
type: object