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.
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:
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.
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.