# Resources

To develop better APIs, you can make use of Tea's API resources.

You can create a new resource by running:

php tea make:resource name=ProductResource

<?php

namespace App\Http\Resources;

use Devlob\Http\Resources\JsonResource;

class ProductResource extends JsonResource
{
    public function toArray(): array
    {
        return [
            'id' => $this->id
        ];
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

It is up to you to decide what data you want your API to return.

Suppose our Product model has 5 attributes, id, code, name, description, and active:

<?php

namespace App\Http\Resources;

use Devlob\Http\Resources\JsonResource;

class ProductResource extends JsonResource
{
    public function toArray(): array
    {
        return [
            'id'          => (int)$this->id,
            'code'        => (int)$this->code,
            'name'        => $this->name,
            'description' => $this->description,
            'active'      => (boolean)$this->active
        ];
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

The above code will return the specified attributes, excluding any other attribute that is not present.

Of course, your resource doesn't need to follow your model attributes, it can return whatever you want, including accessors as described here.

<?php

namespace App\Http\Resources;

use Devlob\Http\Resources\JsonResource;

class ProductResource extends JsonResource
{
    public function toArray(): array
    {
        return [
            'test_one'    => 'Test one',
            'test_two'    => [
                'Test two'
            ],
            'accessor'    => $this->my_accessor
        ];
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# Using a resource

Using a resource is fairly simple, suppose you want to use it inside the show action, you would have the following:

public function show(int $id)
{
    if ( ! $product = Product::find($id)) {
        return $this->notFound('Product does not exist');
    }

    return new ProductResource($product);
}
1
2
3
4
5
6
7
8

# Collections

A resource will return a single entity, a collection will return a collection of a specified entity.

You can create a new collection by running:

php tea make:collection name=ProductCollection resource=ProductResource

<?php

namespace App\Http\Resources;

use Devlob\Http\Resources\ResourceCollection;

class ProductCollection extends ResourceCollection
{
    public $collects = 'App\Http\Resources\ProductResource';

    public function toArray(): array
    {
        return [
            'data' => $this->getCollection()
        ];
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

As you can see the second argument ProductResource notifies the ProductCollection of the data it needs to collect.

You can update the toArray method and change the response structure to your likes.

# Using a collection

Using a collection is fairly simple, suppose you want to use it inside the index action, you would have the following:

public function index()
{
    $products = Product::all();
    
    return new ProductCollection($products);
}
1
2
3
4
5
6

# Relationships

You can also return relationships in your resources:

<?php

namespace App\Http\Resources;

use Devlob\Http\Resources\JsonResource;

class ProductResource extends JsonResource
{
    public function toArray(): array
    {
        return [
            'user' => $this->user() ? (new UserResource($this->user()))->toArray() : null,
        ];
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15