Добавил описание.
Сделал множественную обработку дто
This commit is contained in:
parent
ec118168ba
commit
e4ff986b23
121
Readme.md
121
Readme.md
@ -2,5 +2,124 @@
|
|||||||
[](https://git.rinsvent.ru/symfony/bundles/request-bundle/-/commits/master)
|
[](https://git.rinsvent.ru/symfony/bundles/request-bundle/-/commits/master)
|
||||||
|
|
||||||
Request bundle
|
Request bundle
|
||||||
=
|
===
|
||||||
|
|
||||||
|
Bundle умеет конвертировать request в DTO
|
||||||
|
Полученная DTO валидируется.
|
||||||
|
В случае ошибок выполнение прекращается и возвращаются ошибки.
|
||||||
|
В случае успеха DTO присваиваются в атрибуты и доступны в методе контроллера.
|
||||||
|
|
||||||
|
### Пример запроса
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"signin": {
|
||||||
|
"transport": "phone",
|
||||||
|
"value": "8888888888",
|
||||||
|
"code": "password"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### Пример DTO
|
||||||
|
```php
|
||||||
|
namespace App\DTO\Request;
|
||||||
|
|
||||||
|
use Rinsvent\Data2DTO\Attribute\HandleTags;
|
||||||
|
use Rinsvent\Data2DTO\Attribute\VirtualProperty;
|
||||||
|
use Symfony\Component\Validator\Constraints as Assert;
|
||||||
|
use App\Validator as ProjectAssert;
|
||||||
|
|
||||||
|
use Rinsvent\Data2DTO\Attribute\PropertyPath;
|
||||||
|
use Rinsvent\Data2DTOBundle\Service\Transformer\Request\Headers\Header;
|
||||||
|
use Rinsvent\Data2DTOBundle\Service\Transformer\Request\Headers\UserAgent;
|
||||||
|
use Rinsvent\Data2DTOBundle\Service\Transformer\Request\Server\Ip;
|
||||||
|
|
||||||
|
#[HandleTags(method: 'getTags')]
|
||||||
|
class SigninRequest
|
||||||
|
{
|
||||||
|
#[Assert\NotBlank(message: "error.transport.empty")]
|
||||||
|
public string $transport;
|
||||||
|
|
||||||
|
#[Assert\NotBlank(message: "error.value.empty")]
|
||||||
|
#[Assert\Email(message: "error.email.wrong", groups: "email")]
|
||||||
|
#[ProjectAssert\Phone(message: "error.phone.wrong", groups: "phone")]
|
||||||
|
public string $value;
|
||||||
|
|
||||||
|
#[Assert\NotBlank(message: "error.code.empty")]
|
||||||
|
public string $code;
|
||||||
|
#[VirtualProperty]
|
||||||
|
public Device $device;
|
||||||
|
|
||||||
|
public function getTags(array $data, array $tags)
|
||||||
|
{
|
||||||
|
$transport = $data['transport'] ?? null;
|
||||||
|
if ($transport) {
|
||||||
|
$tags[] = $transport;
|
||||||
|
}
|
||||||
|
return $tags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Device
|
||||||
|
{
|
||||||
|
#[Assert\NotBlank(message: "error.device.id.empty")]
|
||||||
|
#[Header(property: 'X-Device-Id')]
|
||||||
|
public string $deviceId;
|
||||||
|
|
||||||
|
#[Assert\NotBlank(message: "error.device.source.empty")]
|
||||||
|
#[Header(property: 'X-Source')]
|
||||||
|
public string $source;
|
||||||
|
|
||||||
|
#[Assert\NotBlank(message: "error.device.ip.empty")]
|
||||||
|
#[Ip]
|
||||||
|
public ?string $ip = null;
|
||||||
|
|
||||||
|
#[Assert\NotBlank(message: "error.device.user_agent.empty")]
|
||||||
|
#[UserAgent]
|
||||||
|
public string $userAgent;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### Использование
|
||||||
|
```php
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use App\Form\Type\User\DTO\SigninRequest;
|
||||||
|
use App\Service\Entity\UserService;
|
||||||
|
use Rinsvent\RequestBundle\Annotation\RequestDTO;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
|
class UserController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private UserService $us
|
||||||
|
) {}
|
||||||
|
|
||||||
|
#[Route('/v1/signin', name: 'signin', methods: ['POST'])]
|
||||||
|
#[RequestDTO(className: SigninRequest::class, jsonPath: '$.signin')]
|
||||||
|
public function signin(SigninRequest $signinRequest)
|
||||||
|
{
|
||||||
|
$signinResponse = $this->us->signin($signinRequest);
|
||||||
|
|
||||||
|
return new JsonResponse(
|
||||||
|
[],
|
||||||
|
Response::HTTP_OK,
|
||||||
|
[
|
||||||
|
'X-Access-Token' => $signinResponse->getAccessToken(),
|
||||||
|
'X-Refresh-Token' => $signinResponse->getRefreshToken(),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Вариант с несколькими DTO
|
||||||
|
#[Route('/v1/signin', name: 'signin', methods: ['POST'])]
|
||||||
|
#[RequestDTO(className: SigninRequest::class, jsonPath: '$.signin')]
|
||||||
|
#[RequestDTO(className: Device::class)]
|
||||||
|
public function signin2(SigninRequest $signinRequest, Device $device)
|
||||||
|
{
|
||||||
|
$signinResponse = $this->us->signin2($signinRequest, $device);
|
||||||
|
return new JsonResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
@ -2,10 +2,7 @@
|
|||||||
|
|
||||||
namespace Rinsvent\RequestBundle\Annotation;
|
namespace Rinsvent\RequestBundle\Annotation;
|
||||||
|
|
||||||
/**
|
#[\Attribute(\Attribute::IS_REPEATABLE)]
|
||||||
* todo переделать на https://symfony.com/doc/current/components/property_access.html#usage
|
|
||||||
*/
|
|
||||||
#[\Attribute]
|
|
||||||
class RequestDTO
|
class RequestDTO
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
Loading…
Reference in New Issue
Block a user