rinsvent/request-bundle

v0.0.8 2022-11-04 12:30 UTC

This package is auto-updated.

Last update: 2024-04-04 15:39:05 UTC


README

pipeline status coverage report

Request bundle

Bundle умеет конвертировать request в DTO Полученная DTO валидируется. В случае ошибок выполнение прекращается и возвращаются ошибки. В случае успеха DTO присваиваются в атрибуты и доступны в методе контроллера.

Пример запроса

{
  "signin": {
    "transport": "phone",
    "value": "8888888888",
    "code": "password"  
  }
}

Пример DTO

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;
}

Использование

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();
    }
}