如何在 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前端网发表,如需转载,请注明页面地址。
code前端网
