Hey guys,
I'm delighted to share my latest work on the performance of your Laravel API endpoints ๐.
Check out: Laravel Resource Reducer ๐ / Documentation: https://reducer.shipsaas.tech/
Before delving into Laravel Resource Reducer, it's essential to understand the drawbacks of the existing Laravel Resource ๐.
The Laravel Resource
I assume that you all are already familiar with Laravel Resource, aren't you? If not, you can explore it here: https://laravel.com/docs/10.x/eloquent-resources
Simplest tl;dr:
Laravel Resource is a layer to compute your Eloquents into the Responses
Problems
Let's say, we have an endpoint v1/users
which returns an array of users:
[
'data' => [
[
'id' => 1,
'name' => 'Seth Phat',
'email' => 'me@sethphat.com',
'created_at' => '2023-01-01',
'role' => 'ADMIN',
'avatar_url' => '...',
],
[
// ... user 2,
],
// ... more
],
]
Everything is suitable for the listing page, such as rendering users in the table.
However, if we want to use a dropdown of users on another page (for example, to assign a user as a reviewer), then, you won't need all the returned fields, you only need: id
& name
(or additionally, email)
\=> The CONs while reusing the above endpoint:
Redundant fields returned ๐ฅฒ
Slower response ๐ฅฒ
You will end up creating a new endpoint just for the dropdown ๐ฅฒ Development takes more time & the team has to maintain more ๐ฅฒ
Moreover, if you have relationship(s) defined in your UserResource
and you wish to bulk them up in the response, then you will need to do eager-loading before transforming UserResource
, thus you'll have these CONs:
Always need to do the eager-loading in the outer layer ๐ฅฒ
- And maintain that ๐ฅฒ
n*n response size because it bulked up with enormous data ๐ฅฒ
Definitely: slower response ๐ฅฒ
Now that you know the current problems. Let's jump into the super solution ๐
Meets Laravel Resource Reducer
Laravel Resource Reducer helps you to optimize every API request by:
Reduce the response's size, get what you need โญ๏ธ
Responses to API consumers faster ๐
Computation only starts when required, save CPU & memory ๐
Built-in relationship access by using dot notation ๐
Eager-loading on steroids (automated eager-loading, no more N+1 pain) ๐
A simple yet super effective method to skyrocketing your API responding times ๐ฅฐ
If you know about GraphQL, To query for data, we need to define which fields we want to retrieve. Laravel Resource Reducer is heavily inspired from GraphQL approach. โค๏ธ
Usage (from API Consumer)
Let's say, we have this endpoint: v1/users
which returns User[]
User
has these fields: id, name, email, avatar_url, created_at, role (relationship)
Simply add _f[]
or _fields[]
query param
Get
id
,name
https://my-api.com/v1/users?_fields[]=id&_fields[]=name
Get
id
,email
, and the role namehttps://my-api.com/v1/users?_f=id,email,role.name
Isn't it awesome? ๐
Implementation
Resource Reducer
class UserResource extends JsonReducerResource
{
public function definitions(Request $request): array
{
return [
'id' => fn () => $this->id,
'email' => fn () => $this->email,
'created_at' => fn () => $this->created_at,
'role' => RoleResource::makeRelation('role'),
];
}
}
Remember to wrap your fields with a closure, to defer execution ๐
Return responses
// UserController@index
return UserResource::collection($users)->response();
// UserController@show
return (new UserResource($user))->response();
The usage is as same as Laravel Resource ๐
Final words
If this package is helpful, please give it a โญ๏ธโญ๏ธโญ๏ธ.
Consider using Laravel Resource Reducer to optimize & skyrocket your API endpoints ๐ช
Thank you and have a great day!