Eloquent API Response: 4 Ways to Hide Specific DB Fields

When creating API applications, you often don't want to return ALL the data via API, especially sensitive fields like passwords. In this short tutorial, I will show 4 methods to return only the fields which you need.

We will use the same example for all the options: API endpoint /api/users which will return all users.

routes/api.php:

Route::get('users', [UserController::class, 'index']);
class UserController extends Controller
{
public function index()
{
return User::all();
}
}

Now, our task is to NOT return the id field.

The desired result should look similar to this:

[
{
"name": "Manley Reichel",
"email": "okuneva.jeanie@example.net",
"created_at": "2023-02-10T11:51:33.000000Z"
},
{
"name": "Elouise Mitchell",
"email": "kreiger.jaeden@example.net",
"created_at": "2023-02-10T11:51:33.000000Z"
},
{
"name": "Norris Schoen",
"email": "taylor73@example.org",
"created_at": "2023-02-10T11:51:33.000000Z"
},
]

Option 1. Manually Select Fields

The first method would be just to select fields that we only need.

class UserController extends Controller
{
public function index()
{
return User::select('name', 'email', 'created_at')->get();
}
}

Option 2. API Resources

The second method is to use API Resources and return fields only that are needed.

php artisan make:resource UserResource

Then in the UserResource, add the return fields which you need.

app/Http/Resources/UserResource.php:

class UserResource extends JsonResource
{
public function toArray($request): array
{
return [
'name' => $this->name,
'email' => $this->email,
'created_at' => $this->created_at,
];
}
}

And then return the resource in your controller:

use App\Http\Resources\UserResource;
 
class UserController extends Controller
{
public function index()
{
return UserResource::collection(User::all());
}
}

Keep in mind that API Resources wrap the result into another layer of data. To disable that, use JsonResource::withoutWrapping(); in the AppServiceProvider.


Option 3. $hidden Model Property

You can use Laravel $hidden property on your Model. All attributes that are added to the $hidden property are hidden in all API requests.

Default Laravel User model already hides two fields: password and remember_token. So, we add the id there.

app/Models/User.php:

class User extends Authenticatable
{
// ...
protected $hidden = [
'id',
'password',
'remember_token',
];
// ...
}

And in the controller, you can just return your data.

class UserController extends Controller
{
public function index()
{
return User::all();
}
}

Option 4. setHidden() Collection Method

You can use the setHidden() method on the Eloquent Collection to hide fields.

This method overwrites everything which is set in your Model $hidden property, so you need to add fields with sensitive data like passwords to the list also.

class UserController extends Controller
{
public function index()
{
return User::all()->setHidden([
'id', 'email_verified_at', 'password', 'remember_token', 'updated_at'
]);
}
}
avatar

very nice sir, i like the third method

avatar

You should add reaction to your post.

avatar

What would be the "reaction"? You mean "likes" or something? No, I don't think it would be valuable, if you liked the post then you should share it on your social media and that's it :)

👍 6
😍 1

Like our articles?

Become a Premium Member for $129/year or $29/month

Recent Premium Tutorials