Courses

Vue.js 3 + Laravel 11 + Vite: SPA CRUD

Eloquent API Resources to Transform Fields

For now, our data in the table doesn't look pretty. So, in this lesson let's use a Laravel feature called API Resources to transform the data: shorter content excerpt, proper date formatting, and skipping some fields.


First, let's create the Resource class.

php artisan make:resource PostResource

Now, we need to use this resource in the PostController to return all the posts.

app/Http/Controllers/Api/PostController.php:

use App\Http\Resources\PostResource;
 
class PostController extends Controller
{
public function index()
{
return Post::all();
return PostResource::collection(Post::all());
}
}

Basically PostResource collection is a wrapper on top of the Eloquent query which will transform each field into whatever you want.

By default, it doesn't transform anything but we can do that by providing our array.

app/Http/Resources/PostResource.php:

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

But Resource doesn't only change the content and created_at fields. It also adds a data wrapper.

API data wrapper

So, in the frontend if you now check, you would see that the data isn't shown.

data doesn't show

This is because of that added data wrapper from the API Resource. We just need to add this data in the composable where we assign response data to the posts variable.

resources/js/composables/posts.js:

import { ref } from 'vue'
 
export default function usePosts() {
const posts = ref([])
 
const getPosts = async () => {
axios.get('/api/posts')
.then(response => {
posts.value = response.data;
posts.value = response.data.data;
})
}
 
return { posts, getPosts }
}

I know this .data.data looks weird but it is correct: the first .data comes from the default JS API response, and the second .data comes from that Eloquent API Resource wrapper.

Now we have a working table again with modified values. Content now is only 50 characters and created_at data is a string instead of a Carbon instance.

working table using API resources

avatar

In PostController it's necessary to add one more use state use App\Http\Resources\PostResource;