Lzh on GitHub

注解放置 (Annotation placement)

你不应该将所有注解都放在一个大块中,而应将它们分散在你的代码库中,尽可能靠近相关的源代码。

swagger-php 会扫描你的项目并将所有元数据合并到一个 @OA\OpenApi 注解中。

swagger-php v4 开始,所有注解或属性必须与一个结构化元素(class, method, parameter 或者 enum)相关联。

上下文感知 (Context awareness)

swagger-php 会查看注解的上下文,并用诸如属性名称数据类型(docblock 类型和原生类型提示)以及其他一些信息来补充它。

这意味着在很多情况下,没有必要显式地记录所有细节。

示例

<?php

use OpenApi\Attributes as OA;

#[OA\Schema()]
class Product
{
    /**
     * The product name,.
     * @var string
     */
    #[OA\Property()]
    public $name;
}

结果如下

openapi: 3.0.0
components:
  schemas:
    Product:
      properties:
        name:
          description: "The product name"
          type: string
      type: object

就像你写了以下代码一样

<?php

use OpenApi\Attributes as OA;

#[OA\Schema()]
class Product
{
    /**
     * The product name.
     */
    #[OA\Property(
        property: 'name',
        type: 'string',
        description: 'The product name'
    )]
    public string $name;
}

响应媒体类型 (Response media type)

@OA\MediaType 用于描述内容:

<?php

use OpenApi\Attributes as OA;

class Controller
{
    #[OA\Response(
        response: 200,
        description: 'successful operation',
        content: new OA\MediaType(
            mediaType: 'application/json',
            schema: new OA\Schema(ref: '#/components/schemas/User'),
        ),
    )]
    public function endpoint()
    {
    }
}

但由于大多数 API 请求和响应都是 JSON,@OA\JsonContent 允许你通过以下方式进行简化:

<?php

use OpenApi\Attributes as OA;

class Controller
{
    #[OA\Response(
        response: 200,
        description: 'successful operation',
        content: new OA\JsonContent(
            ref: '#/components/schemas/User',
        ),
    )]
    public function endpoint()
    {
    }
}

在处理过程中,@OA\JsonContent 会展开成 @OA\MediaType( mediaType="application/json", @OA\Schema(...) 并生成相同的输出。

使用引用 ($ref)

端点在请求或响应数据上有一些重叠是很常见的。为了遵循 DRY(不要重复你自己)原则,规范允许使用 $ref 重用组件。

#[OA\Schema(
  schema: 'product_id',
  type: 'integer',
  format: 'int64',
  description: 'The unique identifier of a product in our catalog',
)]

结果如下:

openapi: 3.0.0
components:
  schemas:
    product_id:
      description: "The unique identifier of a product in our catalog"
      type: integer
      format: int64

这本身不执行任何操作,但现在你可以通过它在文档树中的路径 #/components/schemas/product_id 来引用这个片段。

#[OA\Property(ref: "#/components/schemas/product_id")]
public $id;
示例
更多关于如何使用 refs 的用例可以在 using-refs 示例中找到。

查询中的数组参数 (Array parameters in query)

根据 样式-值@OA\Parameter(in="query", name="param", ...) 可能会创建像 path?param=123&param=abc 这样的 URL,这在 PHP 中读取参数值时无法正常工作。

解决方案是将名称 param 更改为 param[],这会创建 path?param[]=123&param[]=abc 并产生一个 PHP 数组。

供应商扩展 (Vendor extensions)

该规范允许使用 自定义属性,只要它们以 "x-" 开头即可。因此,所有 swagger-php 注解都有一个 x 属性,它接受一个数组(map),并会展开成 "x-" 属性。

<?php

use OpenApi\Attributes as OA;

#[OA\Info(
    title: 'Example',
    version: '1.0.0',
    x: [
        'some-name' => 'a-value',
        'another' => 2,
        'complex-type' => [
            'supported' => [
                ['version' => '1.0', 'level' => 'baseapi'],
                ['version' => '2.1', 'level' => 'fullapi'],
            ],
        ],
    ],
)]
class OpenApiSpec
{
}

结果如下:

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 的枚举 在两个主要用例中得到支持。

枚举作为值

枚举可以像 stringinteger 或任何其他基本类型一样,作为 enum 列表中的值使用。

基本枚举:

<?php

use OpenApi\Attributes as OA;

enum Suit
{
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

class Model
{
    #[OA\Property(enum: [Suit::Hearts, Suit::Diamonds])]
    protected array $someSuits;
}

结果如下:

openapi: 3.0.0
components:
  schemas:
    Model:
      properties:
        someSuits:
          type: array
          enum:
            - Hearts
            - Diamonds
      type: object

支持值的枚举 (Backed enums)

如果枚举是支持值的枚举,则使用枚举值的支持值 (backing value) 而不是其名称。

枚举模式 (Enum schemas)

使用枚举最简单的方法是将它们注解为 Schema。这使得你可以像在规范中的任何其他模式一样引用它们。

<?php

use OpenApi\Attributes as OA;

#[OA\Schema()]
enum Colour
{
    case GREEN;
    case BLUE;
    case RED;
}

#[OA\Schema()]
class Product
{
    #[OA\Property()]
    public Colour $colour;
}

结果如下:

openapi: 3.0.0
components:
  schemas:
    Colour:
      type: string
      enum:
        - GREEN
        - BLUE
        - RED
    Product:
      properties:
        colour:
          $ref: '#/components/schemas/Colour'
      type: object

支持值的枚举 (Backed enums)

对于支持值的枚举,有两个规则决定是使用名称还是支持值:

  1. 如果没有给出模式类型,则使用枚举名称。
  2. 如果给出了模式类型,且它与支持值类型匹配,则使用枚举的支持值。

使用支持值的枚举名称:

<?php

use OpenApi\Attributes as OA;

#[OA\Schema()]
enum Colour: int
{
    case GREEN = 1;
    case BLUE = 2;
    case RED = 3;
}

#[OA\Schema()]
class Product
{
    #[OA\Property()]
    public Colour $colour;
}

结果如下:

openapi: 3.0.0
components:
  schemas:
    Colour:
      type: string
      enum:
        - GREEN
        - BLUE
        - RED
    Product:
      properties:
        colour:
          $ref: '#/components/schemas/Colour'
      type: object

使用支持值:

<?php

use OpenApi\Attributes as OA;

#[OA\Schema(type: 'integer')]
enum Colour: int
{
    case GREEN = 1;
    case BLUE = 2;
    case RED = 3;
}

#[OA\Schema()]
class Product
{
    #[OA\Property()]
    public Colour $colour;
}

结果如下:

openapi: 3.0.0
components:
  schemas:
    Colour:
      type: integer
      enum:
        - 1
        - 2
        - 3
    Product:
      properties:
        colour:
          $ref: '#/components/schemas/Colour'
      type: object