nelexa / request-dto-bundle
此Symfony扩展为Symfony控制器操作提供请求对象支持
1.3.4
2022-06-21 07:01 UTC
Requires
- php: ^7.4 | ^8.0
- symfony/dependency-injection: ^4.4 | ^5.1 | ^6.0
- symfony/http-kernel: ^4.4 | ^5.1 | ^6.0
- symfony/property-access: ^4.4 | ^5.1 | ^6.0
- symfony/property-info: ^4.4 | ^5.1 | ^6.0
- symfony/serializer: ^4.4 | ^5.1 | ^6.0
- symfony/validator: ^4.4 | ^5.1 | ^6.0
Requires (Dev)
- ext-json: *
- ext-simplexml: *
- doctrine/annotations: ^1.10
- symfony/browser-kit: ^4.4 | ^5.1 | ^6.0
- symfony/css-selector: ^4.4 | ^5.1 | ^6.0
- symfony/framework-bundle: ^4.4 | ^5.1 | ^6.0
- symfony/mime: ^4.4 | ^5.1 | ^6.0
- symfony/phpunit-bridge: ^4.4 | ^5.1 | ^6.0
- symfony/var-dumper: ^4.4 | ^5.1 | ^6.0
Suggests
- doctrine/annotations: For support @Assert annotations
Conflicts
- symfony/framework-bundle: <4.4 | 5.0.*
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。