Home / Symfony / New in Symfony 8.1: Serialize Attribute

New in Symfony 8.1: Serialize Attribute


Kostiantyn Miakshyn
Contributed by
Kostiantyn Miakshyn
in
#49518

Building API endpoints in Symfony often involves the same repetitive boilerplate:
inject the serializer service, call serialize(), create a response with the
proper status code, and configure the Content-Type header:

// src/Controller/GetUserController.php
namespace AppController;

use AppModelUser;
use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentSerializerSerializerInterface;

final readonly class GetUserController
{
    public function __construct(
        private SerializerInterface $serializer
    ) {
    }

    public function __invoke(): JsonResponse
    {
        $data = new User(1, 'Jane Smith', '...');
        $serialized = $this->serializer->serialize($data, 'json');

        return JsonResponse::fromJsonString($serialized, JsonResponse::HTTP_CREATED);
    }
}

Symfony 8.1 streamlines this workflow with the new #[Serialize] attribute.
After installing and configuring the Serializer component, apply the
#[Serialize] attribute to a controller method and return an object or
array instead of a full Response object.

Symfony serializes the result using the format derived from the request (JSON by
default), sets the Content-Type header, and wraps everything in a Response
object automatically:

// ...
use SymfonyComponentHttpKernelAttributeSerialize;

final readonly class GetUserController
{
    #[Serialize]
    public function __invoke(): User
    {
        return new User(1, 'Jane Smith', '...');
    }
}

You can also customize the HTTP status code, response headers, and serialization
context passed to the Serializer component:

// ...
use SymfonyComponentSerializerNormalizerDateTimeNormalizer;

final readonly class CreateProductController
{
    #[Serialize(
        code: 201,
        headers: ['X-Custom-Header' => 'abc'],
        context: [DateTimeNormalizer::FORMAT_KEY => 'd.m.Y H:i:s'],
    )]
    public function __invoke(): ProductCreated
    {
        // ... create the product

        return new ProductCreated(101);
    }
}

The response format is determined from the current request format, so the same
controller can return JSON or XML depending on the route configuration. For
example, a route defined as /products/{id}.{_format} produces JSON for
/products/42.json and XML for /products/42.xml.

If the request asks for a format that is not supported by the Serializer
component, Symfony automatically returns a 415 Unsupported Media Type response.


Sponsor the Symfony project.
Tagged:

Leave a Reply

Your email address will not be published. Required fields are marked *