J'ai récemment vu une question dans la communauté Laravel Brasil et les résultats étaient meilleurs que ça a l'air plus intéressant. Imaginez que vous ayez un UsersResource
implémenté avec ce qui suit :
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\Resource; class UsersResource extends Resource { /** * Transform the resource into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return [ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email ]; } }
Pour une raison quelconque, vous souhaiterez peut-être réutiliser cette classe de ressources sur un autre point de terminaison, mais masquez le champ email
. Cet article vous explique comment y parvenir.
Si vous ne savez pas ce qu'est API Resources
, consultez mon article précédent à ce sujet.
- Première impression sur les ressources API
- Ressources API avec relation imbriquée
1- Projet d'initialisation
Trucs intéressants Commencer avec la section 3.
composer create-project --prefer-dist laravel/laravel api-fields cd api-fields touch database/database.sqlite
Modifiez le fichier .env
, supprimez les paramètres de la base de données et continuez la configuration du projet en utilisant SQLite
DB_CONNECTION=sqlite
php artisan migrate php artisan make:resource UsersResource php artisan make:resource --collection UsersResourceCollection php artisan make:controller UsersController php artisan tinker factory(App\User::class)->times(20)->create(); quit
2- Routage
Assurez-vous de créer un itinéraire dans le fichier api.php
.
Route::apiResource('/users', 'UsersController');
3- Contrôleur
Le contrôleur représente le but recherché. Dans cet exemple, supposons que dans la liste des utilisateurs, nous voulons uniquement les noms de tous les utilisateurs et que dans l'affichage des utilisateurs, nous souhaitons uniquement masquer les adresses e-mail.
<?php namespace App\Http\Controllers; use App\Http\Resources\UsersResource; use App\User; class UsersController extends Controller { /** * Display a listing of the resource. * * @param User $user * @return \Illuminate\Http\Response */ public function index(User $user) { return UsersResource::collection($user->paginate())->hide(['id', 'email']); } /** * Display a user. * * @param User $user * @return \Illuminate\Http\Response */ public function show(User $user) { return UsersResource::make($user)->hide(['id']); } }
Pour y parvenir, nous avons besoin à la fois de UsersResourceCollection
et de UsersResource
pour savoir comment gérer l'appel hide
.
4- Classe UsersResource
Commençons par la méthode show
UsersResource::make
renverra un objet de UsersResource
Par conséquent, nous devrions dévoiler le mystère de hide
, Il. stocke les clés que nous souhaitons supprimer de la réponse.
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\Resource; class UsersResource extends Resource { /** * @var array */ protected $withoutFields = []; /** * Transform the resource into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return $this->filterFields([ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email ]); } /** * Set the keys that are supposed to be filtered out. * * @param array $fields * @return $this */ public function hide(array $fields) { $this->withoutFields = $fields; return $this; } /** * Remove the filtered keys. * * @param $array * @return array */ protected function filterFields($array) { return collect($array)->forget($this->withoutFields)->toArray(); } }
Vous avez terminé ! Nous pouvons maintenant accéder à http://api.dev/api/users/1
et vous remarquerez qu'il n'y a pas de champ id
dans la réponse.
{ "data": { "name": "Mr. Frederik Morar", "email": "darryl.wilkinson@example.org" } }
5- La classe UsersResourceCollection
exécute la méthode index
dans la collection de projets, nous devons apporter les modifications suivantes :
- (1) Assurez-vous
UsersResource::collection
renvoieUsersResourceCollection
Instance - (2) Exposer la méthode
UsersResourceCollection
surhide
- (3) Transmettre les champs cachés à
UsersResource
Concernant (1), il suffit de remplacer la méthode UsersResource
collection
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\Resource; class UsersResource extends Resource { public static function collection($resource) { return tap(new UsersResourceCollection($resource), function ($collection) { $collection->collects = __CLASS__; }); } /** * @var array */ protected $withoutFields = []; /** * Transform the resource into an array. * 将资源转换为一个数组 * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return $this->filterFields([ 'id' => $this->id, 'name' => $this->name, 'email' => $this->email ]); } /** * Set the keys that are supposed to be filtered out. * 设置需要隐藏过滤掉的键 * * @param array $fields * @return $this */ public function hide(array $fields) { $this->withoutFields = $fields; return $this; } /** * Remove the filtered keys. * 删除隐藏的键 * * @param $array * @return array */ protected function filterFields($array) { return collect($array)->forget($this->withoutFields)->toArray(); } }
Concernant (2) et (3), nous devons modifier le fichier UsersResourceCollection
Exposons le méthode et Utiliser les champs cachés pour travailler avec les collections. .hide
<?php namespace App\Http\Resources; use Illuminate\Http\Resources\Json\ResourceCollection; class UsersResourceCollection extends ResourceCollection { /** * @var array */ protected $withoutFields = []; /** * Transform the resource collection into an array. * * @param \Illuminate\Http\Request * @return array */ public function toArray($request) { return $this->processCollection($request); } public function hide(array $fields) { $this->withoutFields = $fields; return $this; } /** * Send fields to hide to UsersResource while processing the collection. * 将隐藏字段通过 UsersResource 处理集合 * * @param $request * @return array */ protected function processCollection($request) { return $this->collection->map(function (UsersResource $resource) use ($request) { return $resource->hide($this->withoutFields)->toArray($request); })->all(); } }
et voyons qu'il n'y a pas de champs http://api.dev/api/users
et id
dans le résultat renvoyé, tout comme la méthode spécifiée dans email
.UsersController
{ "data": [{ "name": "Mr. Frederik Morar" }, { "name": "Angel Daniel" }, { "name": "Brianne Mueller" }], "links": { "first": "http://lab.php71/api-fields-2/public/api/users?page=1", "last": "http://lab.php71/api-fields-2/public/api/users?page=7", "prev": null, "next": "http://lab.php71/api-fields-2/public/api/users?page=2" }, "meta": { "current_page": 1, "from": 1, "last_page": 7, "path": "http://api-fields.lab.php71/api/users", "per_page": 3, "to": 3, "total": 20 } }
plus flexible en masquant certains champs qui peuvent être exposés dans d'autres interfaces. Par exemple, lorsque nous demandons l'interface Resource
, les données de réponse ne contiennent pas le champ /users
, mais lorsque nous demandons avatar
, les données de réponse contiennent le champ /users/99
. avatar