flavacaster/symfony-http-bundle

symfony http request validator bundle

Installs: 155

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 2

Type:symfony-bundle

v1.0.21 2022-12-07 18:48 UTC

README

This package still under development.

Requests injection

How it works:

  • You create request class, describe it structure with JMS serializer annotations and Symfony validation annotations.
  • You inject request in your controller action.
  • Bundle validates request according to your request class, if request is invalid, it throws custom validation exception.
  • If request is valid, it is deserialized to your request class.

Important note: HTTP request fields always come as strings, to validate them correctly, they are soft casted according to type annotations in request class.

You can register listener, that will convert Flavacaster\SymfonyHttpBundle\EventListener\RequestPayloadExceptionListener exception to json response:

# (config/services.yaml)

services:
    # ...
    
    Flavacaster\SymfonyHttpBundle\EventListener\RequestPayloadExceptionListener:
        tags:
            - { name: kernel.event_listener, event: kernel.exception }

Example:

Request class:

use Flavacaster\SymfonyHttpBundle\Interfaces\RequestPayloadInterface;

final class CreateUserRequest implements RequestPayloadInterface
{
    /**
     * @Constraints\NotBlank
     * @Constraints\Type(type="string")
     */
    private string $username;

    /**
     * @Constraints\NotBlank
     * @Constraints\Type(type="integer")
     */
    private int $age;
    
    /**
     * @Constraints\NotBlank
     * @Constraints\Type(type="bool")
     */
    private bool $terms;
}

Controller action:

/**
 * @Route("/api/endpoint")
 */
public function create(CreateUserRequest $request): Response
{
    dd($request);
}

Response for request without parameters:

{
  "code": 422,
  "message": "Validation error occurred",
  "errors": {
    "[username]": "This field is missing.",
    "[age]": "This field is missing.",
    "[terms]": "This field is missing."
  }
}

Nested objects and array of objects

Nested objects and arrays of objects are handled with Flavacaster/symfony-validators-bundle package.

Example:

final class Request implements RequestPayloadInterface
{
    /**
     * @Constraints\NotBlank
     * @NestedObject(NestedObject::class)
     */
    private NestedObject $select2;

    /**
     * @Constraints\NotBlank
     * @NestedObjects(NestedObject::class)
     *
     * @Serializer\Type("array<NestedObject>")
     */
    private array $list;
}

Arrays

One remark about arrays: arrays of integer/float/bool must have @var annotation describing their inner elements scalar type. It needed for soft type casting before validation. Available values: int[], float[], boolean[], string[].

Example:

final class Request implements RequestPayloadInterface
{
    /**
     * @Constraints\NotBlank
     *
     * @Serializer\Type("array")
     * @var float[]
     */
    private array $amounts;
}

AllowExtraFields and AllowMissingFields

Validatior allowExtraFields and allowMissingFields parameters can be overwritten with annotations:

use Flavacaster\SymfonyValidatorsBundle\Options\AllowExtraFields;
use Flavacaster\SymfonyValidatorsBundle\Options\AllowMissingFields;

/**
 * @AllowExtraFields
 * @AllowMissingFields
 */
final class Request implements RequestPayloadInterface
{

}

🥔