Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

PHP 7.4 + SF 5. Library that forces and makes consistent REST API controllers development. Allows to create request objects with pre-controller validation.

Notifications You must be signed in to change notification settings

wojciechpawlinow/rest-api-validator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Request Object validator

A simple library to force and make consistent development REST API controllers. It allows to define structure of the payload and it validator constraints. It also provides much easier way to access validated data from within the controller body.

Installation

composer require pln0w/rest-api-validator

Add following section to your services.yml

Pawly\RestApiValidator\Resolver\CustomRequestResolver:
    arguments:
      - '@validator'
    tags:
      - { name: controller.request_value_resolver }

Each request object must have request_stack service injected, i.e:

User\Infrastructure\Request\RegisterUserRequest:
        arguments:
            - '@request_stack'

Usage

  • Steps to provide validation to your controllers:

    • Create custom request overriding Pawly\RestApiValidator\Request\AbstractCustomRequest
    • Define request class properties that you want to map request values with
    • Add validation constraints to $metadata (no yaml, no addnotations - pure PHP config)
    • (optional) Override getters for properties in needed or add constraint explicit against getter
      See validation docs: https://symfony.com/doc/master/validation.html

    Example 1.

    <?php
    declare(strict_types=1);
    
    namespace User\Infrastructure\Request;
    
    use Pawly\RestApiValidator\Request\AbstractCustomRequest;
    use Symfony\Component\Validator\Constraints as Assert;
    
    class RegisterUserRequest extends AbstractCustomRequest
    {
        protected ?string $email = null;
        protected ?string $password = null;
    
        /**
         * @inheritDoc
         */
        public function getValidationRules()
        {
            return new Assert\Collection([
                'email' => new Assert\Email(),
                'password' => [
                    new Assert\NotBlank(),
                    new Assert\Length(['min' => 6])
                ]
            ]);
        }
    }
    • Create controller having this request injected
    <?php
    declare(strict_types=1);
    
    namespace User\Infrastructure\Controller;
    
    use Pawly\RestApiValidator\Response\ApiResponse;
    use User\Infrastructure\Request\RegisterUserRequest;
    
    final class RegisterUserAction
    {
        public function __invoke(RegisterUserRequest $request): ApiResponse
        {
            // do some stuff ...
            $email = $request->getEmail();
            
            return ApiResponse::json(['email' => $email], ApiResponse::HTTP_OK);
        }
    }

    Different custom request validation example

    <?php
    declare(strict_types=1);
    
    namespace User\Infrastructure\Request;
    
    use Pawly\RestApiValidator\Request\AbstractCustomRequest;
    use Symfony\Component\Validator\Constraints as Assert;
    use Shared\Domain\ValueObject\Email;
    
    class RegisterUserRequest extends AbstractCustomRequest
    {
        protected ?string $email = null;
        protected ?string $password = null;
    
        /**
         * @inheritDoc
         */
        public function getValidationRules()
        {
            return new Assert\Collection([
                'email' => new Assert\Email(),
                'password' => [
                    new Assert\NotBlank(),
                    new Assert\Length(['min' => 6])
                ]
            ]);
        }
      
        public function getEmail(): Email
        {
             return new Email($this->email);
        }
    }
  • Validation errors handling

If request has invalid data, then exception is thrown and handled in subscriber, that will provide following message structure:

{
    "status": 422,
    "message": "Request validation error",
    "details": {
        "email": "This value should not be correct email address.",
        "password": "This value should not be blank."
    }
}

More

Validate responses interface

If you want to ensure you use unified response for controllers, you can enable checking response interface by addint below definition to your services.yaml

Pawly\RestApiValidator\Subscriber\ValidateResponseInterfaceSubscriber:
    tags:
      - { name: kernel.event_subscriber, event: kernel.response }

About

PHP 7.4 + SF 5. Library that forces and makes consistent REST API controllers development. Allows to create request objects with pre-controller validation.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages