3

I am working on an API that will be accessible via a mobile and web app.
I need to send specific fields from the API resource.

I have ItemResource

public function toArray($request) {
    return [
        'id'          => $this->id,
        'name'        => $this->name,
        'description' => $this->description,
        'price'       => $this->price,
        'stock'       => $this->stock,
        'reviews'     => $this->reviews, // this is from reviews table
    ];
}

My Item Model

public function reviews() {
    return $this->hasMany(ItemReview::class);
}

My controller code

return ItemResource::collection(Item::all());

I get this array

{
    "data": {
        "id": 10,
        "name": "Item Name",
        "description": "Item description",
        "price": 410,
        "stock": "815",
        "reviews": [
            {
                "id": 4,       // I don't want to get this field
                "item_id": 10, // I don't want to get this field
                "user_id": 9,  // I want to show user name instead of user id
                "review": "item review."
            },
            {
                "id": 12,      // I don't want to get this field
                "item_id": 10, // I don't want to get this field
                "user_id": 3,  // I want to show user name instead of user id
                "review": "item review."
            }
        ]
    }
}

I want to get an array like this

{
    "data": {
        "id": 10,
        "name": "Item Name",
        "description": "Item description",
        "price": 410,
        "stock": "815",
        "reviews": [
            {
                "user_name": 'jhon',  
                "review": "item review."
            },
            {
                "user_name": 'jhon2',  
                "review": "item review."
            }
        ]
    }
}

I would like to show only specific fields.
How can I implement this?

JustCarty
  • 3,839
  • 5
  • 31
  • 51
ihprince
  • 147
  • 1
  • 2
  • 17

1 Answers1

5

1. Only select what you need

If you add parentheses after reviews, you can return a Builder instance, which will allow you to add queries to the relationship.
With this, you can select the fields you need.

public function toArray($request) {
    return [
        'id'          => $this->id,
        'name'        => $this->name,
        'description' => $this->description,
        'price'       => $this->price,
        'stock'       => $this->stock,
        'reviews'     => $this->reviews()->select('user_name', 'review')->get(),
    ];
}

2. Create a ReviewResource

You can also create a resource for Review that returns it's own data.

class ReviewResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'user_name' => $this->user_name,
            'review' => $this->review,
        ];
    }
}
class ItemResource extends JsonResource
{
    public function toArray($request) {
        return [
            'id'          => $this->id,
            'name'        => $this->name,
            'description' => $this->description,
            'price'       => $this->price,
            'stock'       => $this->stock,
            'reviews'     => ReviewResource::collection($this->reviews),
        ];
    }
}
JustCarty
  • 3,839
  • 5
  • 31
  • 51