Symfony+Open API3:如何简化控制器中JSON响应的OpenAPI定义?
解决NelmioApiDocBundle重复编写响应结构的方案
给你两个亲测可行的方案,解决重复编写API响应结构的问题:
方案一:用OpenAPI组件+JSON文件预定义响应
这个方法直接用JSON文件存响应结构,通过OpenAPI的$ref全局引用,适合不想写PHP类的场景:
- 创建JSON结构文件
在项目根目录下新建config/openapi/responses/success_response.json,写入你的通用响应结构:
{ "type": "object", "properties": { "code": {"type": "number"}, "error": {"type": "boolean"}, "message": {"type": "string"} } }
- 配置NelmioApiDoc加载组件
修改config/packages/nelmio_api_doc.yaml,把JSON文件注册为OpenAPI的全局组件:
nelmio_api_doc: documentation: components: # 先注册schema schemas: SuccessResponse: '$ref': '%kernel.project_dir%/config/openapi/responses/success_response.json' # 再注册可直接引用的响应 responses: Success200: description: 请求成功 content: application/json: schema: '$ref': '#/components/schemas/SuccessResponse'
- 控制器中直接引用
在控制器的PHPDoc里直接用ref指向预定义的响应:
/** * @Route("/login", name="user_login", methods={"POST"}) * * @OA\Response( * response=200, * ref="#/components/responses/Success200" * ) */
方案二:用DTO类+@Model注解(修复你之前无效的问题)
如果更习惯用PHP类管理结构,之前@Model无效大概率是没配置DTO命名空间,按以下步骤来:
- 创建DTO类
在App\Dto下新建SuccessResponseDTO.php,用属性注解定义结构:
namespace App\Dto; use OpenApi\Attributes as OA; #[OA\Schema( type: "object", properties: [ new OA\Property(property: "code", type: "number"), new OA\Property(property: "error", type: "boolean"), new OA\Property(property: "message", type: "string") ] )] class SuccessResponseDTO { // 这里可以加属性对应结构,也可以只留注解用于文档生成 public int $code; public bool $error; public string $message; }
- 配置Nelmio识别DTO命名空间
修改config/packages/nelmio_api_doc.yaml,添加models的命名空间配置:
nelmio_api_doc: models: namespaces: - { namespace: App\Dto, alias: DTO }
- 控制器中用@Model引用
现在就能正常用@Model来复用结构了:
/** * @Route("/login", name="user_login", methods={"POST"}) * * @OA\Response( * response=200, * description="请求成功", * @OA\JsonContent(ref=@Model(type=SuccessResponseDTO::class)) * ) */
注意:如果用的是Symfony 5.4+,推荐用原生PHP属性注解代替PHPDoc,写法更简洁,比如:
use OpenApi\Attributes as OA; #[Route("/login", name: "user_login", methods: ["POST"])] #[OA\Response( response: 200, description: "请求成功", content: new OA\JsonContent(ref: new OA\Schema(ref: "#/components/responses/Success200")) )]
内容的提问来源于stack exchange,提问作者m4n50n1k0
相关产品推荐
相关产品推荐

