Hey folks
Hope your fine! I’m looking for a way to change the default renderer from PhpRenderer to JsonRenderer on a mezzio application. How can I do that? I want to output JSON by default.
I’ve tried to change the dependencies.global.php
to:
return [
'dependencies' => [
'factories' => [
\Laminas\View\Renderer\PhpRenderer::class => \Laminas\View\Renderer\JsonRenderer::class
],
],];
Thanks in advance
Roman
Hello and welcome to our forums! 
For an output in JSON you do not need laminas-view. You can use Laminas\Diactoros\Response\JsonResponse
. Example:
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Laminas\Diactoros\Response\JsonResponse;
// …
public function handle(ServerRequestInterface $request) : ResponseInterface
{
// …
return new JsonResponse($dataToConvertToJson);
}
Can you describe your use case and why the renderer is needed?
Thanks a lot! 
Beside our custom handlers, which already returns a JsonResponse
, I’d like to output every exception the application is throwing as a JSON to the user. Currently the NotFoundHandler
uses LaminasViewRender -> PhpRender if a template was found or it returns a TextResponse
.
I was looking at the NotFoundHandlerFactory
and tried to override the TemplateRendererInterface::class
in dependencies.global.php
:
return [
'dependencies' => [
'factories' => [
TemplateRendererInterface::class => \Laminas\View\Renderer\JsonRenderer::class
],
],];
My goal is to always respond in JSON if no specific renderer/template was set. I’ve already tried to use mezzio/mezzio-problem-details
for this purpose. But a custom exception is now rendered as a HTTP 500 error without the exception message body. Isn’t there a simpler way of doing this without additional dependecies?
Thanks a lot
Roman
You could just create your own ExceptionMiddleware
class ExceptionMiddleware implements MiddlewareInterface
{
/** @var ProblemDetailsResponseFactory */
private $responseFactory;
/**
* Initialize new instance of ExceptionMiddleware
*
* @param ProblemDetailsResponseFactory $responseFactory
*/
public function __construct(ProblemDetailsResponseFactory $responseFactory)
{
$this->responseFactory = $responseFactory;
}
/**
* Catch all exceptions and return a proper json response
*
* @param ServerRequestInterface $request
* @param RequestHandlerInterface $handler
*
* @return ResponseInterface
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
try {
return $handler->handle($request);
} catch (Throwable $throwable) {
return $this->responseFactory->createResponse(
$request,
$this->normalizeHttpCode((int) $throwable->getCode()),
$throwable->getMessage()
);
}
}
/**
* Return 500 if error code is out of range
*
* @param int $code
*
* @return int
*/
private function normalizeHttpCode(int $code): int
{
if ($code < 100 || $code > 599) {
$code = 500;
}
return $code;
}
}
Did you set it up correctly? https://docs.mezzio.dev/mezzio-problem-details/quick-start/#error-handling
You need to pipe the ProblemDetailsMiddleware
and optionaly use the NotFoundHandler
.
Thanks a lot for your help guys! I’ve tried the custom ErrorMiddleware approach but ended up using mezzio/mezzio-problem-details
with a custom factory to include the custom error messages in the output regardless of the debug mode.
class CustomProblemDetailsResponseFactoryFactory
{
public function __invoke(ContainerInterface $container) : ProblemDetailsResponseFactory
{
$config = $container->has('config') ? $container->get('config') : [];
$problemDetailsConfig = $config['problem-details'] ?? [];
$isDebug = $config['debug'] ?? false;
$includeThrowableDetail = $isDebug ?? ProblemDetailsResponseFactory::EXCLUDE_THROWABLE_DETAILS;
$includeThrowableDetail = $problemDetailsConfig['include_exception_details'] ?? $includeThrowableDetail;
$jsonFlags = $problemDetailsConfig['json_flags'] ?? null;
$defaultTypesMap = $problemDetailsConfig['default_types_map'] ?? [];
return new ProblemDetailsResponseFactory(
$container->get(ResponseInterface::class),
$isDebug,
$jsonFlags,
$includeThrowableDetail,
\Mezzio\ProblemDetails\ProblemDetailsResponseFactory::DEFAULT_DETAIL_MESSAGE,
$defaultTypesMap
);
}
}