API Resources in Laravel
Published: 2024-03-24 16:08:38


API resources in Laravel allow you to transform and shape the data you send to your API consumers efficiently. To demonstrate the use of API resources, we'll start by setting up a Laravel project and configuring it to use an SQLite database.

##1. Install Laravel and database content.
Going to explain this with examples. First, we'll install Laravel in your desired directory. Open your terminal or command prompt and navigate to the folder where you want to install Laravel. Then, run the following command:

```
composer create-project laravel/laravel .
```

This command creates a new Laravel project in the current directory.


For this example, we will use SQLite because of its simplicity and ease of setup. Follow these steps to configure your Laravel project to use an SQLite database:

In **.env** file **remove this line** - `DB_DATABASE=laravel` 

And change `DB_CONNECTION=mysql` line to `DB_CONNECTION=sqlite`

Now run 

```
php artisan migrate 
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9sh623hewgtvwode1lsk.png)

Now let us seed and add 10 users. Uncomment this line inside `database\seeders\DatabaseSeeder.php` file.


```
 \App\Models\User::factory(10)->create();
```


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysi3lbjhrn77jpotbv2v.png)

Now you have Laravel installed user table created and 10 users inside it.  


##2. Hiding Model Attributes in Laravel Without API Resources

First, let's define a route that returns a User model instance to demonstrate the effect of hiding attributes. Add the following route to your routes\web.php file:

```
use App\Models\User;

Route::get('/test', function () {
    return User::find(1); // Assuming there's a user with ID 1
});
```

Accessing `http://localhost:8000/test` will display the JSON representation of the first user, including its attributes.

```
{
   "id":1,
   "name":"Mr. Ross Green I",
   "email":"miller.isobel@example.net",
   "email_verified_at":"2024-03-24T14:19:31.000000Z",
   "created_at":"2024-03-24T14:19:32.000000Z",
   "updated_at":"2024-03-24T14:19:32.000000Z"
}
```

Now is the tricky part. We may need to hide `email_verified_at, created_at, updated_at` columns to API user. This is how we does that,

Inside `app\Models\User.php` Use the $hidden Property:

```
/**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',

        //Our properties
        'email_verified_at',
        'created_at',
        'updated_at',
    ];
```

After updating the User model, visit http://localhost:8000/test again. This time, the email_verified_at, created_at, and updated_at fields should no longer be visible in the output:

```
{
   "id": 1,
   "name": "Mr. Ross Green I",
   "email": "miller.isobel@example.net"
}
```

##3. Why API resources here(Conditionally Displaying the Email Attribute with Laravel API Resources)

In certain scenarios, you might want to hide specific information, like an email address, from all users except the owner of that data. Laravel's API resources provide a streamlined approach to achieve this. Below are the steps to create a **UserResource** that conditionally includes the email attribute in its response.

###Create the UserResource

First, we need to generate the UserResource. Open your terminal or command prompt, navigate to your Laravel project directory, and execute the following command:

```
php artisan make:resource UserResource
```

###Modify the UserResource to Conditionally Include the Email

Next, we'll edit the UserResource to conditionally include the email attribute only for the user that owns the data (i.e., the authenticated user). Open the app\Http\Resources\UserResource.php file and modify the toArray method as follows:

```
public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            // Conditionally include the 'email' attribute
            'email' => $this->when($this->id == auth()->id(), $this->email),
        ];
    }
```

In the code above, the toArray method returns an array with id, name, and conditionally email. The email attribute is included only if the id of the resource matches the id of the currently authenticated user, as determined by auth()->id().

##Conclusion
By following these steps, you have successfully created a UserResource that smartly includes the email attribute in the API response only for the authenticated user who owns the data. This method enhances privacy and security by ensuring sensitive information is conditionally exposed.