calin.ionut's avatar

is API Resource faster then going through the data?

I am a little bit confused about the API Resources.

What is the difference between having a RoleResource or just return it as json directly from controller?

Is this less performance going through the data like in the example bellow?

public function index(): JsonResponse
{
	return response()->json(
		Role::with(['permissions'])
		->withCount('users')
		->paginate(10)
	 	->through(fn($role) => [
                'id' => $role->id,
                'title' => $role->title,
                'permissions' => $role['permissions']->map(fn($permission) => [
                    'value' => $permission->id,
                    'label' => $permission->title
                ]),
                'numberOfUsers' => $role->users_count
            ]);
	);
}

or having a RoleResource is much better (speaking of performance). I am not sure behind the scenes, the RoleResource, I think is doing the same....going through all the data and arrange them as you want.

The fronted needs that structure for each entry.

0 likes
7 replies
Glukinho's avatar

API resource allows you to have strict structure of your responses (which structure is defined in dedicated class which is preferable in complex apps), also include metadata:

{
	"data": {...you model with desired structure...},
	"meta": {...some metadata...}
}

If you don't see why use API resources - just don't. When you need them, you'll feel it.

Performance is not an issue, it's just the same in both cases.

martinbean's avatar

@calin.ionut The difference is, the API resource will consistently format the model rather than just relying on its default toArray implementation, which may change over time as you add, change, and remove attributes from your models.

If you’re building an API, I’d strongly recommend using API resources to consistently format model responses rather than just returning models directly from your controllers.

For example:

calin.ionut's avatar

@martinbean I have play a little bit with API Resources but I don't know how to format the response for pagination like I had before.

By default API Resource response is like this:

{
	data: [],
	links: {},
	meta: {}
}

and I want the pagination info on the same level like before, for example:

{
	data: [],
	current_page: 1,
	per_page: 15,
	total: 4409,
	// and so on ..... the pagination info
}

How can I do this?

jlrdw's avatar

@calin.ionut

but I don't know how to format the response for pagination

When returning API data you only send a certain amount if paginated.

The user of the api will handle the get request of the next page of data.

You need to have a set of instructions for your api usage. A how to use page.

Just an example, look at these instructions from this site:

https://partner-apis.adoptapet.com/

It's instructions for adopt a pet.

Of course if it's a mobile app then you design the front end, a mobile app is different as the user can't control the app.

https://laravel.com/docs/12.x/eloquent-resources#pagination

martinbean's avatar

@calin.ionut If you pass a paginator instance to the collection static method of an API resource class—as in my example—then Laravel will automatically add pagination details to the response.

Again:

public function index()
{
    // Create a paginator instance...
    $articles = Article::query()->paginate();

    // Return paginator wrapped in resource...
    return ArticleResource::collection($articles);
}
calin.ionut's avatar

@martinbean Yes, I know that, like I mentioned, all the pagination information is in the meta 'object'. I was wondering if I can pull out all the data from the meta and put it on the root level (side by side with data).

If this is not possible I will have to change the vue component for the databable to handle the correct read for the pagination.

krisi_gjika's avatar

@calin.ionut you would need to implement you own ResourceCollection that extends Illuminate\Http\Resources\Json\ResourceCollection and overwrites toResponse to instead return your custom response in case you pass a paginator instance.

Than your RoleCollection can extend your custom ResourceCollection

Please or to participate in this conversation.