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:
- 创建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; } }
- 注册服务并绑定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
相关产品推荐
相关产品推荐

