withJson jms/serializer


#1

I need to change the behavior of withJson using another library to serialize, which works with Doctrine, in case I will use jms / serializer, is there any way to replace withJson or use a middleware?


#2

Why don’t you directly use jms/serializer then and simply return the serialized JSON string as a response string?

Example:

$app->get('/api', function ($request, $response) {
    $data = []; // fetch data
    $serializer = \JMS\Serializer\SerializerBuilder::create()->build();
    $jsonContent = $serializer->serialize($data, 'json');

    return $response->write($jsonContent);
});

#3

Yes this way it works and the way I’ve been using it, but I just have to repeat the same code every time the api route


#4

In this case there are “tons” of other possibilities. Hard to say whats right for you :slight_smile: You may try to fetch the JMS object from the Slim container or you make use of (Action) classes instead of the Slim route callback. Then implement a abstract BaseAction class with a withJson($response, $data) or encodeJson($data) method and use this method instead of the Slim response withJson method.

Here is just an example for a single action class (controller with only one action), that uses JMS to put the json into the response:

<?php

namespace App\Action;

use JMS\Serializer\SerializerBuilder;
use Psr\Http\Message\ResponseInterface;
use Slim\Container;
use Slim\Http\Response;

abstract class BaseAction
{
    protected $serializer;

    public function __construct(Container $container)
    {
        $this->serializer = $container->get(SerializerBuilder::class);
    }

    protected function withJson(Response $response, $data): ResponseInterface
    {
        return $response->write($this->serializer->serialize($data, 'json'));
    }
}

The slim container (factory)

$container[\JMS\Serializer\SerializerBuilder::class] = function () {
    return \JMS\Serializer\SerializerBuilder::create()->build();
};

Usage

Route: $app->get('/', \App\Action\HomeIndexAction::class)

<?php

namespace App\Action;

use Psr\Http\Message\ResponseInterface;
use Slim\Http\Request;
use Slim\Http\Response;

class HomeIndexAction extends BaseAction
{

    public function __invoke(Request $request, Response $response): ResponseInterface
    {
        $data = [
            'id' => 1234,
            'username' => 'Max',
            'email' => 'max@example.com',
        ];

        return $this->withJson($response, $data);
    }
}

#5

odan
You always give concise answers. Nice to read. On your answers, many can learn and “build” true web applications.
Thanks!