Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

meredevelopment's avatar

Using JSON Resource outside of an API...

I have a JSON Resource, written about 4 years ago, that returns an array exactly as I want it. It includes some pivot table values. Here's a trimmed/example version:

class ProductResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'pivotval1' => $this->whenPivotLoaded('member_product', function () {
                return $this->pivot->pivotval1;
            }),
            'pivotval2' => $this->whenPivotLoaded('member_product', function () {
                return $this->pivot->pivotval2;
            })
        ];
    }
}

When I query a ‘Product’ via the API I get this JSON:

{
    "id": 2,
    "name": "Artificial Grass",
    "pivotval1": "Pivot Value 1",
    "pivotval2": 5000
}

How would I access this from a Trait or Job or somewhere other than the API Controller? Got a real blank on this 🤯

If I do something like this:

$product = Member::find(1234)->products(2)->first();
$resourceresult = new ProductResource($product);

I get this which includes all the pivot stuff nested:

{
    "id": 2,
    "name": "Artificial Grass",
    "pivot": {
        "other_pivot_stuff": true, //etc etc
        "pivotval1": "Pivot Value 1",
        "pivotval2": 5000
    }
}

Is there a way I can get it to return exactly as it does from an API call?

0 likes
9 replies
meredevelopment's avatar

Answering my own question here:

Looks like JsonResource has a resolve method. So this returns it as a flat array as I was expecting:

$product = Member::find(1234)->products(2)->first();
$resourceresult = new ProductResource($product);
$resourceresult->resolve();

...gives me this:

{
    "id": 2,
    "name": "Artificial Grass",
    "pivotval1": "Pivot Value 1",
    "pivotval2": 5000
}

Note though that using the following DOESN'T work for me for some reason, it has to be applied after the Resource is generated:

$resourceresult = new ProductResource($product)->resolve();

If anyone has a better way to do this, or want's to tell me why I'm terrible at PHP, I'm still all ears! Thanks.

1 like
tykus's avatar
tykus
Best Answer
Level 104

You can use the make method:

$resourceresult = ProductResource::make($product)->resolve();
2 likes
meredevelopment's avatar

@tykus Thank you. This answered my question exactly.

For anyone else reading this and looking for the same answer, what I was asking is apparently bad code, stinky, sloppy, whatever. See the other comments from @martinbean and @ben taylor for reasons.

martinbean's avatar

@meredevelopment Why are you trying to use a resource in that way? Resources are for converting models to HTTP responses; not for use in code like this.

Just access properties from your models and relations normally.

meredevelopment's avatar

@martinbean I don't know really. It just seems to work and give me exactly what I want, and have already formatted. Is it 'bad' just from a stinky code point of view, or is there a technical reason I really shouldn't do it? As you will have gathered I'm really ropey with this stuff and very willing to learn.

Ben Taylor's avatar

If you do that, you lose all the benefits the model class has to offer. You won't have access to any of the methods etc.

meredevelopment's avatar

@Ben Taylor Ok thank you Ben. I will see if more light is shed/cast after my reply to Martin above. I don't know enough about this to know what I can/can't use.

martinbean's avatar

@meredevelopment Like I mentioned in my comment, resource classes are meant for preparing models for a HTTP responses; not as some generic data transformer. And as @Ben Taylor also mentions, you would lose any benefits of Eloquent if you did.

You should know your model’s attributes and relations, so just access them normally. I don’t see why you need to try and use a resource to “format” stuff.

Please or to participate in this conversation.