sfmok / request-input-bundle

RequestInputBundle converts request data into DTO inputs objects with validation.
MIT License
37 stars 0 forks source link
dto dto-input input input-validation inputs request-dto

RequestInputBundle

CI codecov Latest Stable Version License

RequestInputBundle converts request data into DTO inputs objects with validation.

Installation

Require the bundle with composer:

composer require sfmok/request-input-bundle

How to use

class PostInput implements InputInterface {

[Assert\NotBlank]

private string $title;

#[Assert\NotBlank]
private string $content;

#[Assert\NotBlank]
private array $tags;

#[SerializedName('author')]
#[Assert\NotBlank]
private string $name;

# getters and setters or make properties public

}

- Use DTO input in your controller action as an argument:
```php
class PostController
{
    # Example with global config
    #[Route(path: '/posts', name: 'create')]
    public function create(PostInput $input): Response
    {
        dd($input);
    }

    # Example with specific config
    #[Route(path: '/posts', name: 'create')]
    #[Input(format: 'json', groups: ['create'], context: ['groups' => ['create']])]
    public function create(PostInput $input): Response
    {
        dd($input);
    }
}

Validations

Deserialization

Whether the request data contains invalid syntax or invalid attributes types a clear 400 json response will return:

{
  "title": 12
}
{
  "title": "Deserialization Failed",
  "detail": "Data error",
  "violations": [
    {
      "propertyPath": "title",
      "message": "This value should be of type string",
      "currentType": "int"
    }
  ]
}

Configuration

# config/packages/request_input.yaml
request_input:
  enabled: true # default value true
  formats: ['json'] # default value ['json', 'xml', 'form']
  skip_validation: true # default value false

You can also override the format using attribute input and specify the format explicitly.

Create DTO input outside controller

You just need to inject InputFactoryInterface e.g:

<?php

declare(strict_types=1);

namespace App\Manager;

use App\Dto\PostInput;
use Sfmok\RequestInput\InputInterface;
use Symfony\Component\HttpFoundation\Request;
use Sfmok\RequestInput\Factory\InputFactoryInterface;

class PostManager
{
    public function __construct(private InputFactoryInterface $inputFactory)
    {
    }

    public function getInput(Request $request): InputInterface
    {
        return $this->inputFactory->createFromRequest($request, PostInput::class);
    }
}

License

The MIT License (MIT). Please see License File for more information.