I want to create my own response factory class but I am confused about the right way to do it. Should I implement the ResponseFactoryInterface? I just want to return my response as formatted json data since my app is an api.
ResponseFactoryInterface::class => function (ContainerInterface $container) {
// should I add my factory class here in the container?
},
Using a custom Response class class for each response type, e.g. JsonResponse, HtmlResponse
extends from a generic Response class. For example, the laminas/laminas-diactoros PSR-7 package contains such Response classes. This concept works not so well in combiniation with the existing $response object that you get from Slim.
Creating a custom “ResponseRenderer” class that takes your $response object and a data array and returns a Response object with the encoded body content and the required HTTP response headers.
@odan thank you so much for your reply.
I’ve just discovered there is a new setResponseFactory method but I couldn’t make it work actually.
Even I’ve set my own response factory it doesn’t work or give any errors.
I think there is no documentation about it
Here is my container.php
use Slim\App;
use Slim\Factory\AppFactory;
use App\Factory\ResponseFactory;
use Illuminate\Database\Connection;
use App\Handler\DefaultErrorHandler;
use Slim\Middleware\ErrorMiddleware;
use Psr\Container\ContainerInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Illuminate\Database\Connectors\ConnectionFactory;
use Illuminate\Container\Container as IlluminateContainer;
return [
'settings' => function () {
return require __DIR__ . '/settings.php';
},
App::class => function (ContainerInterface $container) {
AppFactory::setContainer($container);
AppFactory::setResponseFactory(new ResponseFactory());
return AppFactory::create();
},
ResponseFactoryInterface::class => function (ContainerInterface $container) {
return $container->get(App::class)->getResponseFactory();
},
ErrorMiddleware::class => function (ContainerInterface $container) {
$settings = $container->get('settings')['error'];
$app = $container->get(App::class);
$errorMiddleware = new ErrorMiddleware(
$app->getCallableResolver(),
$app->getResponseFactory(),
(bool)$settings['display_error_details'],
(bool)$settings['log_errors'],
(bool)$settings['log_error_details']
);
$errorMiddleware->setDefaultErrorHandler(DefaultErrorHandler::class);
return $errorMiddleware;
},
Connection::class => function (ContainerInterface $container) {
$factory = new ConnectionFactory(new IlluminateContainer());
$connection = $factory->make($container->get('settings')['db']);
// Disable the query log to prevent memory issues
$connection->disableQueryLog();
return $connection;
},
PDO::class => function (ContainerInterface $container) {
return $container->get(Connection::class)->getPdo();
},
];
Here is my response factory class:
namespace App\Factory;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Slim\Psr7\Response;
class ResponseFactory implements ResponseFactoryInterface
{
public function createResponse(
int $code = 200,
string $reasonPhrase = ''
): ResponseInterface {
$res = new Response($code);
if ($reasonPhrase !== '') {
$res = $res->withStatus($code, $reasonPhrase);
}
return $res;
}
}
According to PSR-17 the ResponseFactoryInterface implementation “has the ability to create responses.”
So I’m not sure if the ResponseFactoryInterface is the right “tool” to build a JSON response.