draw/open-api-bundle

draw/open-api 库集成到 Symfony4。

安装次数: 10,073

依赖者: 1

建议者: 0

安全性: 0

星级: 0

关注者: 3

分支: 0

开放问题: 0

类型:symfony-bundle

0.7.59 2022-04-06 17:47 UTC

README

draw/open-api 到 symfony 4 扩展的集成

第一个目标是能够让程序员以最少的努力生成 Open Api v2 文档。draw/open-api 提供了多种提取器来获取所需信息(例如 PHP)。

与 symfony 的集成允许你使用大多数的 Draw\Component\OpenApi\Schema(别名为 @OpenApi)作为控制器方法上的注解来对其进行文档化。

该扩展包还提供了一些工具,可以在不需要 FOSRestBundle 的情况下提供 RESTful API。

沙箱

要安装沙箱,你可以运行

bin/console draw:open-api:install-sandbox

第一个参数是要安装的版本(例如:v3.52.5)。默认为 master。

我们建议在 composer.json 的 scripts 部分中在 asset:install 之前添加此内容

{
    "scripts": {
            "auto-scripts": {
            "cache:clear": "symfony-cmd",
            "draw:open-api:install-sandbox": "symfony-cmd",
            "assets:install": "symfony-cmd"
        }
    }
}

配置

以下是一个配置示例

draw_open_api: 
    enableDoctrineSupport: null #null will auto detect if DoctrineBundle is install and consider it true
    convertQueryParameterToAttribute: false
    responseConverter: false
    definitionAliases:
        - class: App\Entity\MyUser #This will change reference to class App\Entity\MyUser as User in the Api
          alias: User
        - class: App\Entity\ #This will Remove App\Entity\ from namespace so the class name would be expose instead of the FQCN
          alias: ''
        
    schema: #The schema section is not validate but it must match the Open Api format and will be the starting point of the generated doc
        info:
            title: 'Documentation for Acme API'
            description: 'This is the descriptoin of the 'Acme API'
            termsOfService: 'N\A'
            contact: ~
            version: "5.0"

控制器文档

要为 Open Api 文档化控制器,你必须使用 @OpenApi\Tag 或 @OpenApi\Operation 注解。

/**
 * @OpenApi\Tag("Acme")
 */
public function defaultAction()
{
   //...
}
/**
 * @OpenApi\Operation(
 *     operationId="default",
 *     tags={"Acme"}
 * )
 */
public function defaultAction()
{
   //...
}

如果你计划使用 Open Api 代码生成,我们建议使用 @OpenApi\Operation,因为它将让你控制 operationId,否则它将使用路由名称。

查询参数

如果你想在控制器中注入配置的查询参数,你必须将配置中的 convertQueryParameterToAttribute 设置为 true。

draw_open_api:
  convertQueryParameterToAttribute: true

你还必须给你的控制器添加 Draw\Component\OpenApi\Schema\QueryParameter 注解。这将提供 Open Api 的文档信息,并配置哪些查询参数应该被注入。

/**
 * @OpenApi\QueryParameter(name="param1")
 *
 * @param string $param1
 */
public function createAction($param1 = 'default')
{
   //...
}

视图

要允许自动序列化响应,你必须激活它

draw_open_api:
  responseConverter: true

它将检测你的控制器返回值是否不是响应,并将其根据 Draw\Bundle\OpenApiBundle\Response\Serialization 注解进行序列化。

默认情况下,如果没有注解,序列化上下文将没有任何值,响应状态码为 200。使用视图可以覆盖序列化组、版本和响应状态码。序列化注解也用于 Open Api 文档,headers 属性用于此目的。

如果你的控制器返回 null,默认情况下状态码将被设置为 204(无内容)。

/**
 * @Draw\Bundle\OpenApiBundle\Response\Serialization(
 *     statusCode=201,
 *     serializerGroups={"MyGroup"},
 *     headers={
 *       "X-Acme-CustomHeader"=@OpenApi\Header(type="string", description="The is a custom header")
 *     }
 * )
 */
public function createAction()
{
   //...
}

Draw\Bundle\OpenApiBundle\Response\Serialization 实现 Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface,别名为 draw_open_api_serialization $request->attributes->get('_draw_open_api_serialization');

你可以在每个头中而不是放置 serializerVersion,可以创建一个监听器,根据其他内容设置版本。以下是一个监听器的示例,它将从 URL 路径 /api/v{number}/.... 中获取版本。

<?php namespace App\Listener;

use Draw\Bundle\OpenApiBundle\Response\Serialization;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;

class VersionListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
             //It must be after reading __template attribute but before the serializer listener pass
            KernelEvents::VIEW => ['onKernelView', 31] 
        ];
    }

    public function onKernelView(ViewEvent $event)
    {
        $request = $event->getRequest();
        $pathInfo = $request->getPathInfo();

        $sections = explode('/', $pathInfo, 4);

        if(!isset($sections[2])) {
            return;
        }

        $version = trim($sections[2], 'v');

        if($sections[2] != ('v' . $version)) {
            return;
        }

        $view = $request->attributes->get('_draw_open_api_serialization', new Serialization([]));

        if($view instanceof Serialization && $view->getSerializerVersion() === null) {
            $view->setSerializerVersion($version);
        }

        $request->attributes->set('_draw_open_api_serialization', $view);
    }
}