acsiomatic / http-payload-bundle
Requires
- php: ^8.2
- symfony/framework-bundle: ^6.2
- symfony/mime: ^6.2
- symfony/serializer-pack: ^1.2
- symfony/validator: ^6.2
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.13
- phpstan/phpstan: ^1.9
- phpstan/phpstan-phpunit: ^1.3
- phpstan/phpstan-strict-rules: ^1.4
- phpstan/phpstan-symfony: ^1.2
- phpunit/phpunit: ^10.0
- rector/rector: ^0.15.13
- symfony/browser-kit: ^6.2
- symfony/yaml: ^6.2
This package is auto-updated.
Last update: 2024-11-07 20:09:53 UTC
README
The acsiomatic/http-payload-bundle
handles HTTP payload within Routes that behave like an API Endpoint in Symfony applications.
Features In Short
MapRequestBody is a controller argument attribute which:
- transforms incoming HTTP Request Body into an Object
- validates the object using Symfony Validation
- injects the object into the Route argument
MapUploadedFile is a controller argument attribute which:
- extracts an UploadedFile object from incoming HTTP Request
- validates the object using File Constraints
- injects the object into the Route argument
ResponseBody is a route attribute which:
- looks for a suitable response format through Content Negotiation
- serializes the data returned by the dispatched route
- exceptions thrown after the kernel.controller event are also serialized
- injects the serialized data into the Response object
Installing
composer require acsiomatic/http-payload-bundle
Configuration
# config/packages/acsiomatic_http_payload.yaml acsiomatic_http_payload: request_body: default: formats: ['json'] deserialization_context: [] validation_groups: ['Default'] file_upload: default: constraints: [] response_body: default: formats: ['json'] serialization_context: []
Use Cases
Receiving Objects
The MapRequestBody attribute injects the HTTP Request Body into a Route argument. Incoming data is deserialized and validated before being injected.
# src/Controller/LuckyController.php namespace App\Controller; use Acsiomatic\HttpPayloadBundle\RequestBody\Attribute\MapRequestBody; use App\NumberRange; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\Routing\Annotation\Route; #[AsController] final class LuckyController { #[Route('/lucky/number', methods: ['GET'])] public function number( #[MapRequestBody] NumberRange $range, ): Response { return new Response( (string) random_int($range->min, $range->max) ); } }
# src/NumberRange.php namespace App; use Symfony\Component\Validator\Constraints as Assert; final class NumberRange { #[Assert\GreaterThanOrEqual(0)] public int $min; #[Assert\GreaterThanOrEqual(propertyPath: 'min')] public int $max; }
Receiving Files
The MapUploadedFile attribute fetches the file from the Request and applies custom constraints before injecting it into the Route argument.
# src/Controller/UserController.php namespace App\Controller; use Acsiomatic\HttpPayloadBundle\FileUpload\Attribute\MapUploadedFile; use Symfony\Component\HttpFoundation\File\UploadedFile; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Validator\Constraints\File; #[AsController] final class UserController { #[Route('/user/picture', methods: ['PUT'])] public function picture( #[MapUploadedFile( constraints: new File(mimeTypes: ['image/png', 'image/jpeg']), )] UploadedFile $picture, ): Response { return new Response('Your picture was updated'); } }
Returning Objects
The ResponseBody attribute serializes the object returned by the Route and fills the Response content with it.
# src/Controller/CelebritiesController.php namespace App\Controller; use Acsiomatic\HttpPayloadBundle\ResponseBody\Attribute\ResponseBody; use App\Person; use Symfony\Component\HttpKernel\Attribute\AsController; use Symfony\Component\Routing\Annotation\Route; #[AsController] final class CelebritiesController { #[Route('/celebrities/einstein', methods: ['GET'])] #[ResponseBody] public function einstein(): Person { $person = new Person(); $person->name = 'Albert Einstein'; $person->birthdate = new \DateTimeImmutable('1879-03-14'); return $person; } }
# src/Person.php namespace App; use Symfony\Component\Serializer\Annotation as Serializer; use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer; final class Person { public string $name; #[Serializer\Context([DateTimeNormalizer::FORMAT_KEY => \DateTimeInterface::ATOM])] public \DateTimeImmutable $birthdate; }