If you haven't checked out Inertia, 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
:
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. 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.
php artisan make:resource UserResource
This generates app/Http/Resources/UserResource.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:
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.
public function toResource()
{
return new \App\Http\Resources\UserResource($this);
}
The final state of our controller looks like this:
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 and API Resources. The real power with API Resources comes with relationships!
Top comments (7)
Hello!
That's exactly what I was looking for.
Thank you so much.
A benefit of this approach is that you can check to see if the request requires json and return the resource directly, that way you can have the same controller method handle api and web requests without duplication.
This is what I have done with one application that has a mobile app needing to communicate on some endpoints.
Hey, neat idea.
How exactly would you do this?
Can you provide an example please?
You could use
UserResource::make($user)
instead of creating a new method toResource.Muito bom!
Then how are we supposed to use this resource ?
Great article overall
laravel.com/docs/eloquent-resources