如何在 Laravel 中动态隐藏 API 字段
Laravel Brasil 的社区看到了一个问题,结果比表面上看起来更有趣。想象一下 UsersResource 是通过以下方式实现的:
<?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 ]; } }
出于某种原因,您可能希望在另一个端点上重用资源类,但隐藏电子邮件字段。本文将告诉您如何实现这一目标。
如果您不知道什么是API资源,请查看我之前的文章。
1 - 项目初始化
有趣的事情从第 3 部分开始 2- 路径
确保在文件中创建路径。
Route::apiResource('/users', 'UsersController');
3- 控制器
控制器代表期望的目标。在此示例中,假设我们只想显示用户列表中所有用户的姓名,并且只想隐藏用户屏幕中的电子邮件地址。
<?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']); } }
要实现此目的,我们需要 UsersResourceCollection
和 UsersResource
程序,并且我们需要知道如何处理 hide 调用。
4- UsersResource 类
让我们从 show 方法开始。 UsersResource::make
返回 UsersResource
对象。因此,我们需要揭开能够存储我们想要从答案中删除的密钥的奥秘。
<?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(); } }
完成!现在我们开始了解它,您会注意到响应中没有 ID 字段。?
(3)将隐藏字段传递给UsersResource
对于(1),我们只需要重写UsersResource的集合方法
<?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(); } }
对于(2)和(3),我们需要修改UsersResourceCollection文件。让我们添加一个 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(); } }
就这么简单!现在我们访问一下,发现返回的结果中没有id和email字段,比如UsersController.fields中指定的方法,这样就变得更加灵活了。例如,当我们请求/users接口时,响应数据不包含头像字段,但当我们请求/users/99时,响应数据包含头像字段。
我不建议过多检索 API 资源,因为这可能会使简单的事情变得复杂,因此在请求时隐藏某些字段是一个更简单、更明智的解决方案。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。