Why and how use Laravel Resources

Laravel is a pretty nice PHP framework and provides a lot of useful features. One of them is Resource class. Very often we get some data from an ex. database and send it to our app client. Sending the whole model is very bad option and there are many reasons for that:

  • we probably do not want to disclose our models structure
  • some data may be confidential – maybe our client will not use that fields, but every user will be able to look at request, response and get that data
  • many clients (ex. mobile devices) do not need all the data

Without Resource class we have to create our own class and make some transformations, prepare data from a database for clients. If we decide to use a built-in Resource, it will be much, much simpler. We only have to return such class instances and pass our data into the constructor, and then write what fields we really want to use. There is simple example of Laravel Resource which will prepare our data to send as a JSON:

declare(strict_types=1);

namespace App\Modules\MyModule\Resources;

use Illuminate\Http\Resources\Json\Resource;

class MyModelResource extends Resource
{
   /**
    * @var MyModel
    */
   public $resource;

   public function toArray($request)
   {
      return [
       “id” => $this->resource->getKey(),
       “name” => $this->resource->my_model_name,
       “count” => $this->resource->my_model_attribute,
       (...)
      ];
   }

}

That comment with $var MyModel is optional, but helps some IDEs recognize what model will we use inside our Resource. And there is usage in our controller:

public function getModel(Request $request): JsonResponse
{
   // here some code for get model (or inject it with route)
   $model = MyModel::find($request->id);   

   return response()->json(
       new MyModelResource($model)
   );
}

Simple, clean and elegant, because we transform our model in a separate place. If it’s required, we can modify our data in a more complex way, no problem with that. We can also use… Resource inside Resource, so it’s ok to make something like that:

public function toArray($request)
{
    return [
        "id" => $this->resource->getKey(),
        "name" => $this->resource->my_model_name,
        "relation" => new MyModelRelationResource($this->resource->relation),
        (...)
  ];
}

Collection Resources

What if we have a lot of items and want to send them as a JSON? It’s also not a problem, because we can use a built-in ResourceCollection class to achieve that. There is another example:

declare(strict_types=1);

namespace App\Modules\MyModule\Resources;


use Illuminate\Http\Resources\Json\ResourceCollection;

class MyModuleCollectionResource extends ResourceCollection
{
   public function toArray($request)
   {
       return MyModuleResource::collection($this->collection);
   }
}

Of course we can modify or transform the collection in the same way as in a normal Resource, just a response array. Usage in controller:

public function getModels(Request $request): JsonResponse
{
   $models = MyModel::all();   

   return response()->json(
       new MyModuleCollectionResource($models)
   );
}

As you can see, it’s very easy to use, allows us to make everything more organized and solve a lot of issues.