πŸƒβ€β™‚οΈReducer Resources

Introduction

Laravel Resource Reducer is the SuperSet from Laravel Resource, thus we can use the Reducer just like the way we use normal Resource.

Create a Reducer Resource

Create a resource then change the extends to ShipSaasReducer\Json\JsonReducerResource

namespace App\Http\Resources;

use ShipSaasReducer\Json\JsonReducerResource;

class UserResource extends JsonReducerResource
{
    public function definitions(Request $request): array
    {
        return [
            'id' => fn () => $this->id,
            'email' => fn () => $this->email,
            'created_at' => fn () => $this->created_at,
        ];
    }
}

Remember to wrap your fields/getters in a Closure/Callable.

  • This ensures computation won't start until the right time πŸ˜‰.

When migrating from Resource to Reducer, simply migrate your Resource class by extending ShipSaasReducer\Json\JsonReducerResource, implement the definitions method.

The migration is 1:1 update with no breaking changes πŸ˜‰.

Relationships

To declare a relationship in definition, simply use the ::makeRelation method.

By declaring the relationship, Resource Reducer would be able to automatically do the eager-loading.

E.g.: User has one Role and has many Articles

class UserResource extends JsonReducerResource
{
    public function definitions(Request $request): array
    {
        return [
            'id' => fn () => $this->id,
            'email' => fn () => $this->email,
            'created_at' => fn () => $this->created_at,
            
            'role' => RoleResource::makeRelation('role'),
            'articles' => ArticleResource::makeRelation('articles'),
        ];
    }
}

The required param of makeRelation is the Eloquent's relationship method name.

With the above example, our User model has 2 methods:

  • public function role(): BelongsTo

  • public function articles(): HasMany

Managing eager loading is super freaking hard, everybody knows that. Especially when working with normal Laravel Resources, you have to do the with() or load() in the Controller/Service before passing into the Resource.

No more pain, Reducer ensures your relationship(s) will be loaded based on your need, keep the N+1 problems out of your mind, and build great performance apps.

Return data to Consumer

For single model

public function show(User $user): JsonResponse
{
    return (new UserResource($user))->response();
}

For normal listing

public function index(): JsonResponse
{
    $users = User::limit(10)->get();
    return UserResource::collection($users)->response();
}

For pagination

public function index(): JsonResponse
{
    $users = User::paginate(10);
    return UserResource::collection($users)->response();
}

Last updated