ideas icon indicating copy to clipboard operation
ideas copied to clipboard

Macroable JsonResource

Open hassanzohdy opened this issue 6 years ago • 5 comments

Making the Illuminate\Http\Resources\Json\JsonResource class being Macroable would make it much easier for extension without having to add many traits in many resources.

hassanzohdy avatar Nov 26 '18 19:11 hassanzohdy

Why not make your own BaseJsonResource instead?

deleugpn avatar Nov 26 '18 22:11 deleugpn

@deleugpn Actually that doesn't make any sense, otherwise why would the macros concept be existed if i'm going to create another base class to extend from it?

Let's apply same thing about the query builder or the Arr class, should i extend them all and use it instead of the original class?

hassanzohdy avatar Nov 27 '18 11:11 hassanzohdy

The concept of Macro makes sense when the Framework instantiates a class and you want to add a method into that particular class. If you just extend the Query Builder, that has no effect because the Framework will not instantiate your Query Builder, it will still instantiate it's own. This is where a macro comes into play. As for the JsonResource, the Framework never instantiates it. So it's a much simpler and direct approach for you to have your own base class.

deleugpn avatar Nov 27 '18 12:11 deleugpn

@deleugpn Well i don't think that is the case for the macors.

For instance, why Illuminate\Support\Str and Illuminate\Support\Arr are macroable even they are static classes, i would make another base class for any of it and add my extra method for it? further more the model query builder is macroable as well but only adding methods not like the Marcoable trait as in the query builder case and still, i can make another base model and extend it for my extra methods if i would go based on your approach.

hassanzohdy avatar Dec 09 '18 22:12 hassanzohdy

I'd also like to see this feature. There are some things that creating a BaseJsonResource does not allow you to do.

Say for example, I have BaseJsonResource and UserResource which extends it. I write a function called myFunc() in BaseJsonResource and attempt to call it like so UserResource::collection($userCollection)->myFunc(). This will not work because the collection method returns a class that extends Illuminate\Http\Resources\Json\JsonResource, and not my custom BaseJsonResource.

A real world example is I'd like to set $preserveKeys = true on the fly for individual instances of a resource. I'd like to define the macro ...

JsonResource::macro('withKeys', function () {
    $this->preserveKeys = true;
    return $this;
});

... and call it as $resourceWithKeys = JsonResource::collection($userCollection)->preserveKeys()

Technically there are other ways for me to accomplish this, but not nearly as cleanly. Definitely a super low priority feature, but it definitely has its uses.

peanutsmcgee avatar Jun 01 '21 00:06 peanutsmcgee