You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony+Open API3:如何简化控制器中JSON响应的OpenAPI定义?

解决NelmioApiDocBundle重复编写响应结构的方案

给你两个亲测可行的方案,解决重复编写API响应结构的问题:

方案一:用OpenAPI组件+JSON文件预定义响应

这个方法直接用JSON文件存响应结构,通过OpenAPI的$ref全局引用,适合不想写PHP类的场景:

  1. 创建JSON结构文件
    在项目根目录下新建config/openapi/responses/success_response.json,写入你的通用响应结构:
{
  "type": "object",
  "properties": {
    "code": {"type": "number"},
    "error": {"type": "boolean"},
    "message": {"type": "string"}
  }
}
  1. 配置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'
  1. 控制器中直接引用
    在控制器的PHPDoc里直接用ref指向预定义的响应:
/**
 * @Route("/login", name="user_login", methods={"POST"})
 *
 * @OA\Response(
 *     response=200,
 *     ref="#/components/responses/Success200"
 * )
 */

方案二:用DTO类+@Model注解(修复你之前无效的问题)

如果更习惯用PHP类管理结构,之前@Model无效大概率是没配置DTO命名空间,按以下步骤来:

  1. 创建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;
}
  1. 配置Nelmio识别DTO命名空间
    修改config/packages/nelmio_api_doc.yaml,添加models的命名空间配置:
nelmio_api_doc:
  models:
    namespaces:
      - { namespace: App\Dto, alias: DTO }
  1. 控制器中用@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:25:29