Laravel Inertia and API Resources
Tags: laravel
Published: 2020-04-29 02:27:08

If you haven't checked out [Inertia](https://inertiajs.com/), it's worth a look. It's sort of like a hybrid SPA. I've built a few apps with it and don't see myself not using it for the next while.

Let's take a look at a nice server side tip that I find really useful.

Say we're working on our `/users/{user}` route. Assume we have a `show` method in our `UserController`:

```php
public function show(User $user)
{
    // This is just a helper for Inertia\Inertia::render()
    return inertia('User', [
        'user' => $user,
    ]);
}
```

This will be totally valid and fine. When your `user` variable gets sent to the front end, it will be converted to an array with the `$user->toArray()` method. You can define that on `App\User` and all will be good.

But what happens when you have relationships that you'd like included or you'd like your app to be more flexible? Then you would reach for [API Resources](https://laravel.com/docs/eloquent-resources). Resources allow you to define the shape of your objects when they get sent to API's. Since Inertia is sort of like using an API, we can leverage API Resources to make our objects be sent to our views more reliably and consistently.

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

This generates `app/Http/Resources/UserResource.php`.

```php
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
        ];
    }
}
```

We can refactor our controller to return our resource instead:

```php
public function show(User $user)
{
    return inertia('User', [
        'user' => new \App\Http\Resources\UserResource($user),
    ]);
}
```

Behind the scenes, Inertia will convert this to its "response" version as if you were returning it directly from your controller, but allows you to return a resource for each variable you want to return to your views.

We can go one step further to make things "cleaner" and easier to use when you have multiple controllers returning the same resource. I'm lazy so I like this.

In our `App\User` model, let's add a method called `toResource` and return that resource.

```php
public function toResource()
{
    return new \App\Http\Resources\UserResource($this);
}
```

The final state of our controller looks like this:

```php
public function show(User $user)
{
    return inertia('User', [
        'user' => $user->toResource(),
    ]);
}
```

I love API Resources. Coupled with Inertia, it's a really great developer experience on top of an already amazing experience with Laravel. Make sure to check out [Inertia](https://inertiajs.com/) and [API Resources](https://laravel.com/docs/eloquent-resources). The real power with API Resources comes with [relationships](https://laravel.com/docs/eloquent-resources#conditional-relationships)!