NelmioApiDocBundle
NelmioApiDocBundle 扩展包允许您生成 OpenAPI (Swagger) 格式的文档,并提供一个沙箱以交互式地体验 API。
支持哪些功能?
此扩展包支持 Symfony 路由要求,Symfony 请求映射 (Symfony 属性), PHP 注解, Swagger-Php 注解, FOSRestBundle 注解以及使用 Api-Platform 的应用程序。
对于模型,它支持 Symfony 序列化器 , JMS 序列化器 和 willdurand/Hateoas 库。它还支持 Symfony 表单 类型。
从 4.7 版本和 PHP 8.1 开始支持属性。
安装
打开命令控制台,进入您的项目目录并执行以下命令来下载此扩展包的最新版本
1
$ composer require nelmio/api-doc-bundle
默认情况下,仅记录 /api
下的路由。更新 config/packages/nelmio_api_doc.yaml
中的 nelmio_api_doc.areas.path_patterns
处的正则表达式以更改此策略。
注意
如果您未使用 Flex,请将扩展包添加到您的内核
1 2 3 4 5 6 7 8 9 10 11 12 13
class AppKernel extends Kernel
{
public function registerBundles(): iterable
{
$bundles = [
// ...
new Nelmio\ApiDocBundle\NelmioApiDocBundle(),
];
// ...
}
}
要使用 UI 浏览您的文档,请注册以下路由之一
1 2 3 4 5
# config/routes.yaml
app.swagger_ui:
path: /api/doc
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger_ui }
1 2 3 4 5
# config/routes.yaml
app.redocly:
path: /api/doc
methods: GET
defaults: { _controller: nelmio_api_doc.controller.redocly }
1 2 3 4 5
# config/routes.yaml
app.stoplight:
path: /api/doc
methods: GET
defaults: { _controller: nelmio_api_doc.controller.stoplight }
如果您还想在 JSON 中公开它,请注册此路由
1 2 3 4 5
# config/routes.yaml
app.swagger:
path: /api/doc.json
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger }
由于您刚刚安装了该扩展包,您可能会看到文档中不需要的路由,例如 /_profiler/
。要解决此问题,您可以配置扩展包来过滤要记录的路由
1 2 3 4 5 6 7
# config/packages/nelmio_api_doc.yaml
nelmio_api_doc:
areas:
path_patterns: # an array of regexps (document only routes under /api, except /api/doc)
- ^/api(?!/doc$)
host_patterns: # document only routes with a host of the form api.*
- ^api\.
此扩展包如何工作?
它借助 Describers 从您的 Symfony 应用程序生成 OpenAPI 文档。一个从 SwaggerPHP 属性/注解中提取数据,一个从您的路由中提取数据,等等。
如果您配置了上面的 app.swagger_ui
路由,您可以在 http://example.org/api/doc
浏览您的文档。
使用扩展包
您可以在扩展包配置 documentation.info
部分配置全局信息(查看 OpenAPI 3.0 规范(以前称为 Swagger) 以了解可用字段)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
nelmio_api_doc:
documentation:
servers:
- url: http://api.example.com/unsafe
description: API over HTTP
- url: https://api.example.com/secured
description: API over HTTPS
info:
title: My App
description: This is an awesome app!
version: 1.0.0
x-build: #CommitHash
components:
securitySchemes:
Bearer:
type: http
scheme: bearer
bearerFormat: JWT
security:
- Bearer: []
注意
如果您正在使用 Flex,则此配置默认位于 config/packages/nelmio_api_doc.yaml
下。不要忘记将其调整为您的应用程序!
提示
此配置字段通常可以用于将您的文档存储为 yaml。您可以在 SwaggerPHP 示例的 .yaml
文件中找到。
要记录您的路由,您可以使用 SwaggerPHP 属性/注解和控制器中的 #[Model]
属性/注解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
namespace AppBundle\Controller;
use AppBundle\Entity\Reward;
use AppBundle\Entity\User;
use Nelmio\ApiDocBundle\Annotation\Model;
use Nelmio\ApiDocBundle\Annotation\Security;
use OpenApi\Annotations as OA;
use Symfony\Component\Routing\Annotation\Route;
class UserController
{
/**
* List the rewards of the specified user.
*
* This call takes into account all confirmed awards, but not pending or refused awards.
*
* @Route("/api/{user}/rewards", methods={"GET"})
* @OA\Response(
* response=200,
* description="Returns the rewards of an user",
* @OA\JsonContent(
* type="array",
* @OA\Items(ref=@Model(type=Reward::class, groups={"full"}))
* )
* )
* @OA\Parameter(
* name="order",
* in="query",
* description="The field used to order rewards",
* @OA\Schema(type="string")
* )
* @OA\Tag(name="rewards")
* @Security(name="Bearer")
*/
public function fetchUserRewardsAction(User $user)
{
// ...
}
}
控制器方法上的普通 PHPDoc 块用于摘要和描述。
提示
使用属性/注解的示例可以在 SwaggerPHP 示例中找到。但是,与这些示例不同的是,当使用此扩展包时,您无需指定路径,并且可以轻松记录模型以及下面描述的其他一些属性,因为可以使用 Symfony 集成自动记录它们。
提示
NelmioApiDocBundle 理解 symfony 的控制器属性。在控制器内部使用这些属性允许此扩展包自动创建必要的文档。更多信息可以在这里找到:Symfony 属性。
使用模型
如上面的示例所示,该扩展包提供了 #[Model]
属性。使用它代替定义引用,扩展包将推断您的模型属性。
注意
模型可以是 Symfony 表单类型、Doctrine ORM 实体或通用 PHP 对象。
此属性有两个选项
type
用于指定模型的类型
1 2 3 4 5 6
/**
* @OA\Response(
* response=200,
* @Model(type=User::class)
* )
*/
groups
用于指定用于(反)序列化模型的序列化组
1 2 3 4 5 6
/**
* @OA\Response(
* response=200,
* @Model(type=User::class, groups={"non_sensitive_data"})
* )
*/
groups
也可以用于指定用于(反)序列化模型的约束验证组,但这必须在配置中启用
1 2 3
nelmio_api_doc:
use_validation_groups: true
# ...
启用此功能后,模型中设置的组将同时应用于序列化器属性和验证器约束。以下面的模型类为例
1 2 3 4 5 6 7 8 9 10 11
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
class UserDto
{
/**
* @Groups({"default", "create", "update"})
* @Assert\NotBlank(groups={"default", "create"})
*/
public string $username;
}
NotBlank
约束将仅应用于 default
和 create
组,但不应用于 update
。更实际地说:username
属性将显示为模型创建和默认组的 required
,但不显示为更新组的 required
。当使用代码生成器构建 API 客户端时,这通常会转化为客户端验证和类型。NotBlank
添加 required
将导致该属性类型不可为空,例如。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
use OpenApi\Annotations as OA;
/**
* shows `username` as `required` in the OpenAPI schema (not nullable)
* @OA\Response(
* response=200,
* @Model(type=UserDto::class, groups={"default"})
* )
*/
/**
* Similarly, this will make the username `required` in the create
* schema
* @OA\RequestBody(@Model(type=UserDto::class, groups={"create"}))
*/
/**
* But for updates, the `username` property will not be required
* @OA\RequestBody(@Model(type=UserDto::class, groups={"update"}))
*/
提示
当在 #[OA\Response]
和 #[OA\Parameter]
的根部使用时,#[Model]
会自动嵌套在 #[OA\Schema]
中。
媒体类型默认为 application/json
。
要直接在 #[OA\Schema]
, #[OA\Items]
或 #[OA\Property]
中使用 #[Model]
,您必须使用 $ref
字段
1 2 3 4 5 6 7 8 9 10 11 12 13
/**
* @OA\Response(
* @OA\JsonContent(ref=@Model(type=User::class))
* )
*
* or
*
* @OA\Response(@OA\XmlContent(
* @OA\Schema(type="object",
* @OA\Property(property="foo", ref=@Model(type=FooClass::class))
* )
* ))
*/
Symfony 表单类型
您可以使用 documentation
选项自定义表单字段的文档
1 2 3 4 5 6
$builder->add('username', TextType::class, [
'documentation' => [
'type' => 'string', // would have been automatically detected in this case
'description' => 'Your username.',
],
]);
请参阅 OpenAPI 3.0 规范 以查看 documentation
选项的所有可用字段(它接受与 OpenApi Property
对象相同的字段)。
通用 PHP 对象
提示
如果您未使用 JMS Serializer,则 Symfony PropertyInfo 组件 用于描述您的模型。它支持 doctrine 属性/注解、类型提示,甚至 PHP doc 块。当使用 Symfony 序列化器时,它还支持序列化组。
如果您正在使用 JMS Serializer,则默认情况下使用 JMS 序列化器的元数据来描述您的模型。其他信息从 PHP doc 块注释中提取,但属性类型必须在 JMS 属性/注解中指定。
注意:如果您正在使用序列化上下文(例如 Groups),则每个排列都将被视为单独的路径。例如,如果您在代码的不同位置定义了以下两个变体
1 2 3 4 5 6 7 8 9 10 11 12 13
/**
* A nested serializer property with no context group
*
* @JMS\VirtualProperty
* @JMS\Type("ArrayCollection<App\Response\ItemResponse>")
* @JMS\Since("1.0")
*
* @return Collection|ItemResponse[]
*/
public function getItems(): Collection|array
{
return $this->items;
}
1
@OA\Schema(ref=@Model(type="App\Response\ItemResponse", groups=["Default"])),
即使 Default 和 blank 相同,它也会生成两个不同的组件模式(ItemResponse,ItemResponse2)。这是按设计进行的。
如果您更喜欢使用 Symfony PropertyInfo 组件(您将无法使用 JMS 序列化组),您可以在配置中禁用 JMS 序列化器支持
1 2
nelmio_api_doc:
models: { use_jms: false }
或者,也可以通过在 serializationContext 中设置 useJms
来选择每个端点不使用 JMS 序列化器
1
/** @OA\Response(response=200, @Model(type=UserDto::class, serializationContext={"useJms"=false})) */
当将 JMS 序列化器与 willdurand/Hateoas (和 BazingaHateoasBundle)结合使用时,将自动提取 HATEOAS 元数据
4.35
TypeInfo 组件 在 Symfony 7.2 中作为稳定功能引入。
如果您想自定义对象属性的文档,可以使用 #[OA\Property]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
use Nelmio\ApiDocBundle\Attribute\Model;
use OpenApi\Annotations as OA;
class User
{
/**
* @var int
* @OA\Property(description="The unique identifier of the user.")
*/
public $id;
/**
* @OA\Property(type="string", maxLength=255)
*/
public $username;
/**
* @OA\Property(ref=@Model(type=User::class))
*/
public $friend;
/**
* @OA\Property(description="This is my coworker!")
*/
public setCoworker(User $coworker) {
// ...
}
}
请参阅 OpenAPI 3.0 规范 以查看 #[@OA\Property]
的所有可用字段。