在 Laravel 中动态隐藏 API 字段的方法
我最近在LaravelBrasil社区看到一个问题,结果比看起来更有趣。想象一下你有一个UsersResource用下面的实现:
$this->id, 'name'=>$this->name, 'email'=>$this->email ]; } }
出于某种原因,您可能希望在另一个端点上重新使用该资源类,但隐藏email字段。这篇文章就是告诉你如何实现这一点的。
如果你不知道APIResources是什么,请查看我之前关于这个的文章。
- FirstImpressiononAPIResources
- APIResourceswithNestedRelationship
1-初始化项目
有趣的东西从第3节开始.
composercreate-project--prefer-distlaravel/laravelapi-fields cdapi-fields touchdatabase/database.sqlite
编辑.env文件,删除数据库设置并使用SQLite
DB_CONNECTION=sqlite
继续设置项目
phpartisanmigrate phpartisanmake:resourceUsersResource phpartisanmake:resource--collectionUsersResourceCollection phpartisanmake:controllerUsersController phpartisantinker factory(App\User::class)->times(20)->create(); quit
2-路由
确保在api.php文件中创建一个路由。
Route::apiResource('/users','UsersController');
3-控制器
控制器代表了期望的目标。在这个例子中,让我们假设在用户列表中,我们只想要所有用户的名字,而在用户显示中,我们只想隐藏电子邮件地址。
paginate())->hide(['id','email']); } /** *Displayauser. * *@paramUser$user *@return\Illuminate\Http\Response */ publicfunctionshow(User$user) { returnUsersResource::make($user)->hide(['id']); } }
为了达到这个目的,我们需要UsersResourceCollection和UsersResource同时知道如何处理hide调用。
4-UsersResource类
让我们从 show方法开始. UsersResource::make将会返回 UsersResource的对象.因此,我们应该揭开 hide的神秘面纱,它可以存储我们期望从响应中移除的键.
filterFields([ 'id'=>$this->id, 'name'=>$this->name, 'email'=>$this->email ]); } /** *Setthekeysthataresupposedtobefilteredout. * *@paramarray$fields *@return$this */ publicfunctionhide(array$fields) { $this->withoutFields=$fields; return$this; } /** *Removethefilteredkeys. * *@param$array *@returnarray */ protectedfunctionfilterFields($array) { returncollect($array)->forget($this->withoutFields)->toArray(); } }
大功告成!现在我们可以访问http://api.dev/api/users/1,你会发现响应中已经没有id字段了。
{ "data":{ "name":"Mr.FrederikMorar", "email":"darryl.wilkinson@example.org" } }
5-UsersResourceCollection类
执行项目集合中的index方法,我们需要作出如下修改:
(1)确保 UsersResource::collection返回UsersResourceCollection实例
(2)在 UsersResourceCollection上公开hide方法
(3)将隐藏的字段传递给 UsersResource
关于(1),我们只需要重写 UsersResource中的collection方法
collects=__CLASS__; }); } /** *@vararray */ protected$withoutFields=[]; /** *Transformtheresourceintoanarray. *将资源转换为一个数组 * *@param\Illuminate\Http\Request *@returnarray */ publicfunctiontoArray($request) { return$this->filterFields([ 'id'=>$this->id, 'name'=>$this->name, 'email'=>$this->email ]); } /** *Setthekeysthataresupposedtobefilteredout. *设置需要隐藏过滤掉的键 * *@paramarray$fields *@return$this */ publicfunctionhide(array$fields) { $this->withoutFields=$fields; return$this; } /** *Removethefilteredkeys. *删除隐藏的键 * *@param$array *@returnarray */ protectedfunctionfilterFields($array) { returncollect($array)->forget($this->withoutFields)->toArray(); } }
关于(2)和(3)我们需要修改UsersResourceCollection文件.让我们公开hide方法并使用隐藏字段处理集合。.
processCollection($request); } publicfunctionhide(array$fields) { $this->withoutFields=$fields; return$this; } /** *SendfieldstohidetoUsersResourcewhileprocessingthecollection. *将隐藏字段通过UsersResource处理集合 * *@param$request *@returnarray */ protectedfunctionprocessCollection($request) { return$this->collection->map(function(UsersResource$resource)use($request){ return$resource->hide($this->withoutFields)->toArray($request); })->all(); } }
就是这么简单!现在我们访问http://api.dev/api/users 看到返回结果中没有了id和email字段了如在UsersController中的指定方法.
{ "data":[{ "name":"Mr.FrederikMorar" },{ "name":"AngelDaniel" },{ "name":"BrianneMueller" }], "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 } }
6-总结
本文目标是让Resource类通过隐藏一些在其他接口允许暴露的字段从而变得更加灵活。例如当我们请求/users接口时响应的数据是不包含avatar字段的,但是当请求/users/99时响应的数据里包含avatar字段。
我不推荐过度重复去请求API资源,因为它很可能会把简单的事情变得更加复杂,所以说在请求的时候隐藏某些特定的字段是更简单、更合理的解决方案。
以上所述是小编给大家介绍的在Laravel中动态隐藏API字段的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。