Back to Course |
React.js + Inertia in Laravel 11: From Scratch

Protect Your Inertia Data with API Resources

In this lesson, I want to show that you can still use API resources or Eloquent API resources to transform that data, although you don't use API directly.


Why Use API Resources?

For example, in the initial project, using React with API, the content was stripped to 50 symbols and the created at date was formatted as a date time string. For that, the API Eloquent resources were used. API resources can also be used with Inertia.

Why do you need to do that? There are two reasons:

  1. Format the data however you want.
  2. Limiting data that is passed to the front-end.

Keep in mind that all that data is passed to the front-end if you are dealing with a web project without API, Inertia, view, or anything that is on the back end. So, in the front-end, the user doesn't see all that data unless it is shown in the blade.

But in the React and Inertia case, everything is seen on the front end. Everything can be seen if you pass posts as Post:all() to the front end. If you open the network tab in the developer tools in the data-page, all the data is JSON.

You may not want to pass all that, or you may want some things to be hidden. For example, although you don't show some columns in the React, they are still shown here, which may, again, be a security issue, especially if you're working with user data.

So, you may accidentally pass some token or some hidden field. For both of those reasons, I suggest transforming your data. Of course, you could manually select all fields, but I would still suggest using API Resource.


How To Use API Resources

You can create the API Resource using an Artisan command.

php artisan make:resource PostResource

app/Http/Resources/PostResource.php:

class PostResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'content' => substr($this->content, 0, 50) . '...',
'created_at' => $this->created_at->toDateString(),
];
}
}

Now, API Resources can be used in the Controller.

app/Http/Controllers/PostController.php:

use App\Models\Post;
use Inertia\Inertia;
use Inertia\Response;
use App\Http\Resources\PostResource;
use Illuminate\Http\Resources\Json\JsonResource;
 
class PostController extends Controller
{
public function index(): Response
{
$posts = Post::all();
$posts = PostResource::collection(Post::all());
 
return Inertia::render('Posts/Index', compact('posts'));
}
}

The difference is that API Resource now wraps returned data with a data key. There are two ways to fix it.

The first option is to disable wrapping in the AppServiceProvider.

app/Providers/AppServiceProvider.php:

use Illuminate\Http\Resources\Json\JsonResource;
 
class AppServiceProvider extends ServiceProvider
{
// ...
 
public function boot(): void
{
JsonResource::withoutWrapping();
}
}

Or, when iterating posts, add the data key.

resources/js/Pages/Posts/Index.jsx:

// ...
 
{posts && posts && posts.map((post) => (
{posts && posts.data && posts.data.map((post) => (
 
// ...

On the posts page, content is now only 50 symbols and created_at as a string.