I'm creating a RESTful API in ZF2 returning JSON responses for each route. For one of the routes, I need to return a 404 response, but return $this->notFoundAction();
is not acceptable as it returns a view rather than JSON. I'm therefore doing the following:
$response = $this->getResponse();
$response->setStatusCode(404);
return new JsonModel(array(
'error_message' => "Client $clientRef doesn't exist"
));
Testing this, I get the response fine with a 404 status code, and my error message is displayed. However, there are other Zend-generated messages included as part of the response:
{
"error_message": "Client test-client doesn't exist",
"message": "Page not found.",
"reason": "error-controller-cannot-dispatch",
"display_exceptions": true,
"controller": "Timesheet\\Controller\\TimesheetRest",
"controller_class": null
}
If I change display_not_found_reason
and display_exceptions
both to false
in the config, then it will remove some of the additional details, but message
still remains:
{
"error_message": "Client test-client doesn't exist",
"message": "Page not found."
}
How do I remove all the extra details from the response body?
Note that I only get these messages when returning a 404 status. When returning 400, 403, or 409, it is only my error message that is returned, without any additional messages.
Not sure if it's relevant, but the config file for the module in question is as follows (note I have 2 controllers, one for the front-end, and one for the API):
<?php
return array(
'controllers' => array(
'invokables' => array(
'Timesheet\Controller\Timesheet' => 'Timesheet\Controller\TimesheetController',
'Timesheet\Controller\TimesheetRest' => 'Timesheet\Controller\TimesheetRestController'
)
),
'router' => array(
'routes' => array(
'timesheet' => array(
'type' => 'Segment',
'options' => array(
// Change this to something specific to your module
'route' => '/timesheet[/:action][/:id]',
'defaults' => array(
// Change this value to reflect the namespace in which
// the controllers for your module are found
'__NAMESPACE__' => 'Timesheet\Controller',
'controller' => 'Timesheet',
'action' => 'index'
),
'constraints' => array(
'action' => 'index|pending|review|save|submit|unauthorised',
'id' => '[1-9][0-9]*'
)
)
),
'timesheet-rest' => array(
'type' => 'Segment',
'options' => array(
// Change this to something specific to your module
'route' => '/api/timesheet[/:id]',
'defaults' => array(
// Change this value to reflect the namespace in which
// the controllers for your module are found
'__NAMESPACE__' => 'Timesheet\Controller',
'controller' => 'TimesheetRest',
),
'constraints' => array(
'id' => '[1-9][0-9]*'
)
)
),
)
),
'view_manager' => array(
'strategies' => array(
'ViewJsonStrategy'
),
'template_path_stack' => array(
'Timesheet' => __DIR__ . '/../view'
)
)
);
message
After looking through Zend/Mvc/View/Http/RouteNotFoundStrategy
there is a function prepareNotFoundViewModel
which is what adds message
to the response. However, this only happens when message
isn't already defined. Changing my code to this:
$response = $this->getResponse();
$response->setStatusCode(404);
return new JsonModel(array(
'message' => '',
'error_message' => "Client $clientRef doesn't exist"
));
would then give me a response body of:
{
"message": "",
"error_message": "Client test-client doesn't exist"
}
which at least removes confusion between the two messages.
message
However, changing the code to return the response directly, instead of using a JsonModel
, stops message
from being injected at all. The following code:
$response = $this->getResponse();
$response->setStatusCode(404);
$response->setContent(json_encode(array(
'error_message' => "Client $clientRef doesn't exist"
)));
return $response;
gives this as a response:
{
"error_message":"Client test-client doesn't exist"
}