crtl / request-dto-resolver-bundle
将请求反序列化并验证为对象
0.0.3
2024-06-04 22:33 UTC
Requires
- php: >=8.2
- psr/log: ^3.0
- symfony/dependency-injection: ^7.1
- symfony/http-kernel: ^7.1
- symfony/validator: ^7.1
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.58
- jaschilz/php-coverage-badger: ^2.0
- phpunit/phpunit: ^11.1
This package is auto-updated.
Last update: 2024-09-05 23:50:29 UTC
README
用于简化请求 DTO 实例化和验证的 Symfony 扩展包。
功能
- 自动 DTO 处理:
从Request
数据中立即创建并验证与控制器动作中类型提示的数据传输对象 (DTO),从而简化操作。 - Symfony 验证器集成:
利用 Symfony 内置的验证器来确保数据完整性并符合您的验证规则。 - 嵌套 DTO 支持:
通过支持查询和正文参数的嵌套 DTO,简化了复杂请求结构的处理,便于管理层次数据。
安装
composer crtl/request-dto-resolver-bundle
配置
在您的 Symfony 应用程序中注册此扩展包。请将以下内容添加到您的 config/bundles.php
文件中
return [ // other bundles Crtl\RequestDTOResolverBundle\CrtlRequestDTOResolverBundle::class => ["all" => true], ];
用法
步骤 1:创建 DTO
创建一个表示请求数据的类。使用 #[RequestDTO]
注解该类,并使用以下属性将请求参数映射到属性上。
namespace App\DTO; use Crtl\RequestDTOResolverBundle\Attribute\BodyParam; use Crtl\RequestDTOResolverBundle\Attribute\FileParam; use Crtl\RequestDTOResolverBundle\Attribute\HeaderParam; use Crtl\RequestDTOResolverBundle\Attribute\QueryParam; use Crtl\RequestDTOResolverBundle\Attribute\RouteParam; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Validator\Constraints as Assert; #[RequestDTO] class ExampleDTO { // Matches someParam in request body #[BodyParam, Assert\NotBlank] public ?string $someParam; // Matches file in uploaded files #[FileParam, Assert\NotNull] public mixed $file; // Matches Content-Type header in headers #[HeaderParam("Content-Type"), Assert\NotBlank] public string $contentType; // Pass string to param if property does not match param name. // Matches queryParamName in query params #[QueryParam("queryParamName"), Assert\NotBlank] public string $query; // Matches id #[RouteParam, Assert\NotBlank] public string $id; // Nested DTOs are supported for BodyParam and QueryParam #[BodyParam("nested"), Assert\Valid] public ?NestedRequestDTO $nestedBodyDto; #[QueryParam("nested")] public ?NestedRequestDTO $nestedQueryParamDto; // Optionally implement constructor which accepts request object public function __construct(Request $request) { } }
重要提示
除了请求 DTO 的属性外,每个属性都必须接受?string
类型。
否则,PHP 可能会在运行时抛出 TypeError,因为我们无法在验证之前知道请求是否包含有效的数据类型。
默认情况下,每个参数都会通过其属性名称解析。
如果属性名称与参数名称不匹配,您可以为每个*Param
属性的构造函数传递一个可选的字符串(见AbstractParam::__construct
)。
每个 DTO 可以定义一个可选的构造函数,该构造函数接受一个
Request
对象
步骤 2:在控制器中使用 DTO
将 DTO 注入到您的控制器动作中。RequestValueResolver
将自动实例化和验证 DTO。
namespace App\Controller; use App\DTO\ExampleDTO; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class ExampleController extends AbstractController { #[Route("/example", name: "example")] public function exampleAction(ExampleDTO $data): Response { // $data is an instance of ExampleDTO with validated request data return new Response("DTO received and validated successfully!"); } }
步骤 3:处理验证错误
当验证失败时,会抛出
Crtl\RequestDTOResolverBundle\Exception\RequestValidationException
。
您可以创建事件监听器或覆盖默认的异常处理程序来处理验证错误。
namespace App\EventListener; use Crtl\RequestDTOResolverBundle\Exception\RequestValidationException; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpKernel\Event\ExceptionEvent; class RequestValidationExceptionListener implements EventSubscriberInterface { public static function getSubscribedEvents() { return [ KernelEvents::EXCEPTION => "onKernelException", ]; } public function onKernelException(ExceptionEvent $event) { $exception = $event->getThrowable(); if ($exception instanceof RequestValidationException) { $response = new JsonResponse([ "error" => "Validation failed", "details" => $exception->getViolations(), ], JsonResponse::HTTP_BAD_REQUEST); $event->setResponse($response); } } }
许可
此扩展包受 MIT 许可证许可。有关更多详细信息,请参阅 LICENSE 文件。