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?
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);
});
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
In this case there are “tons” of other possibilities. Hard to say whats right for you 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);
}
}
odan
You always give concise answers. Nice to read. On your answers, many can learn and “build” true web applications.
Thanks!