Invoke return $this->asJson(null);
in controller
or
$response->format = Response::FORMAT_JSON;
$response->data = null;
will output nothing.
In standard json, the null value must be output a 'null' string.
But when I set output format to json, and value is null, it output nothing.
I think the right output is a 'null' string, hope fixed.
this is expected according to the docs of Response::$data
: https://github.com/yiisoft/yii2/blob/9b01ca275f891c245c2e840ed93c87f715c04e70/framework/web/Response.php#L125-L126 what is the use case of returning null from a controller?
@cebe I think that use case is irrelevant here - empty string is invalid JSON. "null response" should return null
encoded as JSON.
>> JSON.parse('')
SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data
>> JSON.parse('null')
null
Might this not be a breaking change?
Strict correctness of the JSON encoding isn't necessarily the requirement if Yii, according to its documentation, specifies that a PHP null
means "don't output anything". People might be using it.
Hmm... you're right. It may be used.
People might be using it.
For what? Empty JSON is invalid response. You can almost always say "we can not fix this bug, because people may rely on it".
@tom-- But people has use \Yii::$app->response->format = Response::FORMAT_JSON;
That mean wan't output as json format. If output nothing, that format must not be JSON.
What status now? any changes?
the problem here is the duplicate meaning of null
, it could be a valid JSON value OR mean that property data
should not be converted to populate property content
.
To fix this for Controller::asJson()
we could add something like
$response->format = Response::FORMAT_JSON;
if ($data === null) {
$response->data = null;
$response->content = 'null';
} else {
$response->data = $data;
}
@cebe I don't think we should modify content
directly in Controller::asJson()
.
The better solution is to change JsonResponseFormatter
behavior like this:
protected function formatJson($response)
{
if ($response->data !== null) {
$options = $this->encodeOptions;
if ($this->prettyPrint) {
$options |= JSON_PRETTY_PRINT;
}
$response->content = Json::encode($response->data, $options);
} else {
$response->content = 'null';
}
}
I'm ready to make PR with this change and updated tests
Please do.
I'm using json format for my REST API. After your breaking changes I'm receiving 'null' as response' body for endpoint requested with method OPTIONS instead of empty output.
@neoka4 Had the same problems with this change, I filed a bug in the forum: https://forum.yiiframework.com/t/after-upgrade-to-2-0-16-json-parse-unexpected-non-whitespace-character-after-json-data/125065
@beatep please report as issue at github.
@beatep See https://github.com/yiisoft/yii2/issues/17111
That was already reported in #17111, I just saw.
Most helpful comment
@cebe I don't think we should modify
content
directly inController::asJson()
.The better solution is to change
JsonResponseFormatter
behavior like this: