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 :)

avatar

Thanks

avatar
João Antônio Hamerski Copetti

API Resources is problably the cleaner option if you want to dynamically show attributes throgouth the application, like using user rules and permissions.

If you know you never want to show some attribute, hidden directly in the model attribute $hidden is probably a better solution.

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 59 courses (1056 lessons, total 42 h 44 min)
  • 78 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials