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": "[email protected]", "created_at": "2023-02-10T11:51:33.000000Z" }, { "name": "Elouise Mitchell", "email": "[email protected]", "created_at": "2023-02-10T11:51:33.000000Z" }, { "name": "Norris Schoen", "email": "[email protected]", "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' ]); }}
very nice sir, i like the third method