-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[8.x] Add ability to customize json options on JsonResource response #40208
[8.x] Add ability to customize json options on JsonResource response #40208
Conversation
What about resource collections? Does anything need to be done for them? |
No, no change needed for ResourceCollection. But you make me remember that the same change must be done in PaginatedResourceResponse Currently afk, I will make the change tomorrow. |
I will reopen the PR once the changes are pushed. |
Well, you were right, some changes were needed for ResourceCollections... Let me know if something looks wrong |
Really good work @bastien-phi |
Thanks ! |
This has introduced an error for me: namespace App\Http\Resources;
use App\Models\User;
use Illuminate\Http\Resources\Json\ResourceCollection;
class UserResourceCollection extends ResourceCollection
{
public $collects = User::class;
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return $this->collection->map(function ($user) use ($request) {
// ...
});
}
// ...
} Using this ResourceCollection throws Should I not use model classes in I've been following this guide to make it work the way I want and it has worked just fine before. |
@bastien-phi can you fix the issue from above? Otherwise it'll be best to revert this PR. |
@driesvints It looks like an unexpected usage of ResourceCollection. As documentation states, As it worked with that, I will open a PR to fix this. |
@bastien-phi you're correct. @ninjami-matti it seems you're using a model here but |
Fair enough 👍 I would still argue that it is slightly confusing that you can still make I set the But indeed I see now that setting a |
@ninjami-matti If you want to bypass auto-discovery of underlying resource, you can just rename your resource collection in order to make it not ending with class UserCollectionResource extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return $this->collection->map(function (\App\Models\User $user) use ($request) {
// ...
});
}
// ...
} will work |
That's true! However, I'm just too much of a stickler on following "correct" naming conventions 😄 So I went ahead and changed my collections and resources to reflect the correct usage and the problem is now gone. Thanks for the tip! |
Currently, it is possible to customize the options with
JsonResource::withResponse($request, $response)
doing something likeThe behaviour is that the original json is decoded then re-encoded with the given options
framework/src/Illuminate/Http/JsonResponse.php
Lines 119 to 124 in 676ba54
framework/src/Illuminate/Http/JsonResponse.php
Lines 63 to 66 in 676ba54
framework/src/Illuminate/Http/JsonResponse.php
Lines 73 to 92 in 676ba54
Unfortunately, json_encode with no option is destructive :
json_decode(json_encode(['float' => 3.0]), true)
gives['float' => 3]
.With this,
$response->setEncodingOptions(JSON_PRESERVE_ZERO_FRACTION);
returns a json likeThat is, there is currently no way to encode JsonResources with
JSON_PRESERVE_ZERO_FRACTION
.This PR adds the ability to customize json serialization options for responses from JsonResource at the time that the JsonResponse is created, providing the ability to preserve the zero fraction of floats.
Why do you need JSON_PRESERVE_ZERO_FRACTION btw ?
Imagine a Order model with a
quantity
property as float and you want to test some simple api call likePretty easy no ?
Well, if your factory is defined with
and faker generates a float with 1 digit, your test will pass. But if faker generates
3.0
for example, the test will fail withQuite annoying to have randomly failing tests...