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

ApiPlatform如何为Invoice ApiResource新增返回PDF格式的自定义路由

你的实现思路完全符合Api-Platform自定义项操作的标准规范,是合理的。针对你遇到的两个问题,可按以下方案解决,也可根据需求选择更简化的实现方式:

问题1:解决application/pdf MIME类型不支持报错

你不需要额外编写Encoder,更简便的方案是直接在控制器中返回原生Symfony Response对象,跳过Api-Platform的序列化流程,适配PDF二进制输出场景:
修改DocumentController的__invoke方法:

use Symfony\Component\HttpFoundation\Response;

public function __invoke(Invoice $data): Response
{
    $pdfContent = $this->documentService->createDocumentForInvoice($data);
    return new Response(
        $pdfContent,
        Response::HTTP_OK,
        [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'inline; filename="invoice-' . $data->getId() . '.pdf"'
        ]
    );
}

如果确实需要保留Api-Platform的序列化流程,则需注册自定义PDF Encoder:

  1. 创建Encoder类:
use Symfony\Component\Serializer\Encoder\EncoderInterface;

class PdfEncoder implements EncoderInterface
{
    public const FORMAT = 'pdf';

    public function encode($data, string $format, array $context = []): string
    {
        // 此处$data就是控制器返回的PDF内容,直接返回即可
        return $data;
    }

    public function supportsEncoding(string $format): bool
    {
        return $format === self::FORMAT;
    }
}
  1. 注册服务并绑定MIME类型,在config/services.yaml中添加:
services:
    App\Serializer\PdfEncoder:
        tags:
            - { name: serializer.encoder, priority: 250 }

framework:
    serializer:
        mime_types:
            pdf: ['application/pdf']

问题2:补充OpenApi接口文档

直接在Invoice实体的自定义操作注解中添加openapi_context配置即可,无需额外编写装饰器:

#[ApiResource(itemOperations: [
    'get',
    'put',
    'patch',
    'delete',
    'get_document' => [
        'method' => 'GET',
        'path' => '/invoices/{id}/document',
        'controller' => DocumentController::class,
        'output_formats' => ['application/pdf'],
        'openapi_context' => [
            'summary' => '获取指定发票的PDF文档',
            'responses' => [
                '200' => [
                    'description' => '发票PDF文件',
                    'content' => [
                        'application/pdf' => [
                            'schema' => [
                                'type' => 'string',
                                'format' => 'binary'
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ],
])]

可选替代方案

如果你不想在实体上添加额外操作注解,也可以单独创建一个自定义路由,手动实现参数转换获取Invoice对象,但当前你使用的自定义项操作方案已经是该场景下最简洁、复用Api-Platform能力最多的实现方式,没有必要更换。

内容的提问来源于stack exchange,提问作者LBA

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 01:36:04