check24 / apitk-dtomapper-bundle
此包提供映射辅助工具,将REST动作映射到DTO并将它们序列化。
Requires
- php: ^7.4 || ^8.0
- check24/apitk-common-bundle: ^2.2 || ^3.0
- doctrine/annotations: ^1.6
- friendsofsymfony/rest-bundle: ^3.0
- nelmio/api-doc-bundle: ^3.2
- symfony/config: >= 5.3 <6.0
- symfony/dependency-injection: >= 5.3 <6.0
- symfony/framework-bundle: >= 5.3 <6.0
- symfony/http-kernel: >= 5.3 <6.0
- symfony/serializer: >= 5.3 <6.0
Requires (Dev)
- captainhook/captainhook: ^5.0
- captainhook/plugin-composer: ^5.1
- friendsofphp/php-cs-fixer: ^2.13
- google/protobuf: ^3.19
- phpmd/phpmd: ^2.6
- phpstan/phpstan: ^0.12
- symfony/error-handler: >= 5.3 <6.0
This package is auto-updated.
Last update: 2024-09-05 00:45:36 UTC
README
概述
此包为RESTful API添加了版本化的DTO支持。
安装
使用composer安装此包
composer require check24/apitk-dtomapper-bundle
用法
设置
将以下内容添加到您的services.yaml中,以便包可以自动加载和使用映射服务
services: App\DtoMapper\: resource: '../src/DtoMapper' public: true
编写映射器
在src/DtoMapper
文件夹(或您配置的任何文件夹)中创建一个映射器类,该类实现MapperInterface
并将传入的数据转换为单个DTO
use Shopping\ApiTKDtoMapperBundle\DtoMapper\MapperInterface; class UserV1Mapper implements MapperInterface { /** * @param User $data * @return Dto\UserV1 */ public function map($data): Dto\UserV1 { $userDto = new Dto\UserV1(); $userDto->setId($data->getId()) ->setUsername($data->getUsername()) ->setEmail($data->getEmail()); return $userDto; } }
在您的控制器中,将@Rest\View()
注解替换为相应的@Dto\View()
,并指明要使用的映射器
use FOS\RestBundle\Controller\Annotations as Rest; use Shopping\ApiTKDtoMapperBundle\Annotation as DtoMapper; /** * @Rest\Get("/v1/users") * @DtoMapper\View(dtoMapper="App\DtoMapper\UserV1Mapper") * * @param EntityManagerInterface $entityManager * @return User[] */ public function getUsersV1(EntityManagerInterface $entityManager) { $userRepository = $entityManager->getRepository(User::class); $users = $userRepository->findAll(); return $users; }
现在,该包会自动将您在动作中返回的任何内容转换为DTO,使用给定的映射器。当您在控制器中返回数据数组时,映射器将对数组中的每个元素进行调用。您无需担心这一点。
如果您想跳过数组中的某些元素,可以抛出UnmappableException
。
此外,该包自动生成带有代码200和相应的DTO模式的swagger响应(分别是一个DTO数组),因此您无需添加冗余的@SWG\Response()
。为此,只需确保您的映射器有一个正确的返回类型提示(例如public function map($data): FoobarDto
),并且您的控制器动作有一个返回注解,该注解声明返回的是数组还是对象(例如* @return Foobar[]
)。您仍然可以通过自己的@SWG\Response()
注解来覆盖此设置。
将数组转换为集合
如果您在控制器中返回数组,它将按此方式序列化。如果您不想使用数组或由于技术限制(例如protobuf)无法使用数组,您可以指示该包将数组转换为集合类。
要将控制器返回的数组转换为集合,请将MapperCollectionInterface
与MapperInterface
一起实现到您的映射器中。
示例
use Shopping\ApiTKDtoMapperBundle\DtoMapper\MapperCollectionInterface; use Shopping\ApiTKDtoMapperBundle\DtoMapper\MapperInterface; class UserV1Mapper implements MapperInterface, MapperCollectionInterface { /** * @param Dto\UserV1[] $items */ public function mapCollection(array $items): Dto\UserV1Collection { $collection = new UserV1Collection(); $collection->setItems($items); return $collection; } /** * @param Dto\UserV1 $data */ public function map($data): Dto\UserV1 { $userDto = new Dto\UserV1(); $userDto->setId($data->getId()) ->setUsername($data->getUsername()) ->setEmail($data->getEmail()); return $userDto; } }
这将在通过map
映射所有项目后调用mapCollection
。您可以在mapCollection
方法中初始化您的集合类。这里返回的对象将替换控制器响应的内容。
序列化DTO视图
如果您希望以serialize($dto)
的方式返回DTO而不是JSON,请实现可用的DTO视图处理程序。
//fos_rest.yaml fos_rest: view: mime_types: dto: ['application/vnd.dto'] # You can specify whatever mime type you want, just map it to "dto". service: view_handler: app.view_handler exception: serializer_error_renderer: true
//services.yaml services: app.view_handler: autowire: true autoconfigure: false public: false parent: fos_rest.view_handler.default calls: - ['registerHandler', ['dto', ['@Shopping\ApiTKDtoMapperBundle\Handler\PhpViewHandler', 'createResponse']]]
当使用Accept: application/vnd.dto
头调用API时,您将获得一个不可序列化的DTO字符串。
异常也会被序列化。当kernel.debug
设置为false
(=在生产环境中)时,会省略堆栈跟踪、文件名、行号和前面的异常,以避免泄露可能敏感的信息。
序列化Protobuf视图
如果您希望返回序列化的Protobuf对象。
//fos_rest.yaml fos_rest: view: mime_types: proto: ['application/x-protobuf'] # You can specify whatever mime type you want, just map it to "proto". service: view_handler: app.view_handler exception: serializer_error_renderer: true
//services.yaml services: app.view_handler: autowire: true autoconfigure: false public: false parent: fos_rest.view_handler.default calls: - ['registerHandler', ['proto', ['@Shopping\ApiTKDtoMapperBundle\Handler\ProtobufViewHandler', 'createResponse']]]