fenix007 / request-dto-bundle
此 Symfony 扩展为 Symfony 控制器动作提供请求对象支持
1.2.2
2021-08-18 21:16 UTC
Requires
- php: ^7.4 | ^8.0
- symfony/dependency-injection: ^5.0
- symfony/http-kernel: ^5.0
- symfony/property-access: ^5.0
- symfony/property-info: ^5.0
- symfony/serializer: ^5.0
- symfony/validator: ^5.0
Requires (Dev)
- ext-json: *
- ext-simplexml: *
- doctrine/annotations: ^1.10
- symfony/framework-bundle: ^5.0
- symfony/test-pack: ^1.0
- symfony/var-dumper: ^5.0
Suggests
- doctrine/annotations: For support @Assert annotations
Conflicts
- symfony/framework-bundle: <5.0.0
This package is not auto-updated.
Last update: 2024-09-27 10:11:19 UTC
README
RequestDtoBundle
此 Symfony 扩展为 Symfony 控制器动作提供请求对象支持。
安装
使用 composer 安装此扩展
composer require nelexa/request-dto-bundle
使用示例
要将对象指定为控制器动作的参数,对象必须实现以下 4 个接口之一
\Nelexa\RequestDtoBundle\Dto\QueryObjectInterface
用于 GET 或 HEAD 请求方法的查询参数。\Nelexa\RequestDtoBundle\Dto\RequestObjectInterface
用于 POST、PUT 或 DELETE 请求方法的请求参数(例如,Content-Type: application/x-www-form-urlencoded)或 GET 和 HEAD 请求方法的查询参数。\Nelexa\RequestDtoBundle\Dto\RequestBodyObjectInterface
用于 POST、PUT、DELETE 请求体的内容(例如,Content-Type: application/json)。\Nelexa\RequestDtoBundle\Dto\ConstructRequestObjectInterface
用于在类构造函数中将请求映射到数据传输对象。
创建请求 DTO
use Nelexa\RequestDtoBundle\Dto\RequestObjectInterface; use Symfony\Component\Validator\Constraints as Assert; class UserRegistrationRequest implements RequestObjectInterface { /** @Assert\NotBlank() */ public ?string $login = null; /** * @Assert\NotBlank() * @Assert\Length(min="6") */ public ?string $password = null; /** * @Assert\NotBlank() * @Assert\Email() */ public ?string $email = null; }
在控制器中使用
<?php declare(strict_types=1); use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Validator\ConstraintViolationListInterface; class AppController extends AbstractController { /** * @Route("/sign-up", methods={"POST"}) */ public function registration( UserRegistrationRequest $userRegistrationRequest, ConstraintViolationListInterface $errors ): Response { $data = ['success' => $errors->count() === 0]; if ($errors->count() > 0){ $data['errors'] = $errors; } else{ $data['data'] = $userRegistrationRequest; } return $this->json($data); } }
如果您将类型为 \Symfony\Component\Validator\ConstraintViolationListInterface
的参数声明为可空,则如果没有错误,它将是 null
。
... /** * @Route("/sign-up", methods={"POST"}) */ public function registration( UserRegistrationRequest $userRegistrationRequest, ?ConstraintViolationListInterface $errors ): Response { return $this->json( [ 'success' => $errors === null, 'errors' => $errors, ] ); } ...
如果没有声明 \Symfony\Component\Validator\ConstraintViolationListInterface
参数,则将抛出 \Nelexa\RequestDtoBundle\Exception\RequestDtoValidationException
异常,该异常将被转换为 json
或 xml
格式。
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class AppController extends AbstractController{ /** * @Route("/sign-up", methods={"POST"}) */ public function registration(UserRegistrationRequest $userRegistrationRequest): Response { return $this->json(['success' => true]); } }
发送 POST 请求
curl 'https://127.0.0.1/registration' -H 'Accept: application/json' -H 'Content-Type: application/x-www-form-urlencoded' --data-raw 'login=johndoe'
响应
HTTP/1.1 400 Bad Request
Content-Type: application/problem+json
内容响应
{ "type": "https://tools.ietf.org/html/rfc7807", "title": "Validation Failed", "detail": "password: This value should not be blank.\nemail: This value should not be blank.", "violations": [ { "propertyPath": "password", "title": "This value should not be blank.", "parameters": { "{{ value }}": "null" }, "type": "urn:uuid:c1051bb4-d103-4f74-8988-acbcafc7fdc3" }, { "propertyPath": "email", "title": "This value should not be blank.", "parameters": { "{{ value }}": "null" }, "type": "urn:uuid:c1051bb4-d103-4f74-8988-acbcafc7fdc3" } ] }
从请求构建 DTO(版本 1.1.0+)
use Nelexa\RequestDtoBundle\Dto\ConstructRequestObjectInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\ConstraintViolationListInterface; class ExampleDTO implements ConstructRequestObjectInterface { /** @Assert\Range(min=1) */ private int $page; /** * @Assert\NotBlank * @Assert\Regex("~^\d{10,13}$~", message="Invalid phone number") */ private string $phone; public function __construct(Request $request) { $this->page = $request->request->getInt('p', 1); // sanitize phone number $phone = (string) $request->request->get('phone'); $phone = preg_replace('~\D~', '', $phone); $this->phone = (string) $phone; } public function getPage(): int { return $this->page; } public function getPhone(): string { return $this->phone; } } class AppController extends AbstractController { public function exampleAction( ExampleDTO $dto, ConstraintViolationListInterface $errors ): Response { $data = [ 'page' => $dto->getPage(), 'phone' => $dto->getPhone(), 'errors' => $errors, ]; return $this->json($data, $errors->count() === 0 ? 200 : 400); } }
变更日志
变更记录在 发布页面 中进行说明。
许可证
MIT 许可证 (MIT)。有关更多信息,请参阅 LICENSE。