# Formatting API Responses with Laravel Resource Classes

> How to produce clean API responses with Laravel Resource classes without leaking your database model directly to clients.

- Published: 2018-02-04
- Category: Web Development
- Tags: Laravel, API
- Reading time: 3 min read
- Source: https://www.muhammetsafak.com.tr/en/blog/formatting-api-responses-with-laravel-resource-classes/
- Language: en-US
- Author: Muhammet Şafak

---
One of the traps I fell into most often while building APIs was returning Eloquent models directly as responses. I'd write `return $user;`, it worked, I moved on. Then a new field got added to the model, or a relationship, or a sensitive column — and the client suddenly received fields it never expected. The **API Resource** classes introduced in Laravel 5.5 offer a clean solution to [this problem](/en/blog/writing-json-api-endpoints-with-laravel/).

## The Problem: Returning the Model Directly

Consider a `User` model with fields like `email`, `name`, `password`, `remember_token`, `created_at`, and `updated_at`. If you write this in a controller:

```php
<?php

public function show(User $user)
{
    return response()->json($user);
}
```

`password` and `remember_token` will be included in the response. You can prevent this by populating the `$hidden` array, but that means pushing response-shaping responsibility onto the model itself. As the model grows, keeping track of what to show and what to hide becomes increasingly painful.

There's another scenario too: you add an `is_admin` field to the model, it gets sent to the client, and the client starts displaying it to users. Then you rename that field — and the client breaks. When you leak the model directly, the boundary between your database schema and your API contract disappears. These two things need to be kept separate.

## Creating an API Resource Class

You can scaffold a resource class quickly with Laravel's Artisan command:

```bash
php artisan make:resource UserResource
```

This generates `app/Http/Resources/UserResource.php`. Fill in the `toArray` method however you like:

```php
<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class UserResource extends Resource
{
    public function toArray($request)
    {
        return [
            'id'         => $this->id,
            'name'       => $this->name,
            'email'      => $this->email,
            'created_at' => $this->created_at->toDateTimeString(),
        ];
    }
}
```

Using it in a controller is straightforward:

```php
<?php

public function show(User $user)
{
    return new UserResource($user);
}
```

That's it. The client now sees exactly what it needs to see — nothing more.

## Collection Responses

When you need to return a list instead of a single model, `ResourceCollection` comes into play. The quickest approach is calling `UserResource::collection()`:

```php
<?php

public function index()
{
    return UserResource::collection(User::all());
}
```

This also works with pagination; when you return [`paginate()`](/en/blog/pagination-filtering-and-sorting-in-rest-apis/), Laravel automatically appends `meta` and `links` blocks.

## Conditional Fields

Sometimes I only want to include a field in the response under certain conditions — for example, showing a token only on a newly created record. The `when` method handles this:

```php
<?php

public function toArray($request)
{
    return [
        'id'    => $this->id,
        'name'  => $this->name,
        'email' => $this->email,
        'token' => $this->when($this->wasRecentlyCreated, $this->api_token),
    ];
}
```

When `wasRecentlyCreated` returns false, the `token` key is completely absent from the response — not `null`, completely gone. That distinction matters.

## Related Data

Say you also want to include a user's roles in the response. You can define another resource class and call it from within:

```php
<?php

public function toArray($request)
{
    return [
        'id'    => $this->id,
        'name'  => $this->name,
        'roles' => RoleResource::collection($this->whenLoaded('roles')),
    ];
}
```

The value of `whenLoaded` is this: if the relationship hasn't been eager-loaded, it won't add that field to the response at all. So when you write `User::with('roles')->find($id)` in the controller, roles appear; when you don't, they don't. No N+1 query traps, no unnecessary data fetched per request.

## Adding Extra Metadata to the Response

Sometimes you need to wrap the response with additional information: a status code, a message, or some custom metadata beyond pagination. You can override the `with` method in your resource class for this:

```php
<?php

public function with($request)
{
    return [
        'meta' => [
            'api_version' => '1.0',
        ],
    ];
}
```

## The Value of This Layer Becomes Clear as Clients Multiply

When I first used a Resource class, the project had a single client: a web interface. Later, a mobile app was required. Mobile needed different field naming — `name` instead of `full_name`, `joined_at` instead of `created_at`. I was able to write a separate `UserMobileResource` for mobile without breaking the web client; both serve the same `User` model in different shapes. If you'd been returning the model directly, there would be no clean way to make that distinction.

In any project with multiple clients — or even a single client that evolves over time — this transformation layer insulates database changes from the API contract. Adding a new column no longer means breaking the existing response.

## Conclusion

API Resource classes initially look like "just another layer to add." But once I used one on a real project, I never wanted to go back to wiring a model straight to a response. Being able to see and manage exactly which fields get sent out from a single file keeps the client side safe from unexpected changes. Especially when there are multiple consumers — a mobile app, a web app, third-party integrators — the value of this layer becomes all the more apparent.
