文章转自专业的Laravel开发者社区,原文链接:https://learnku.com/laravel/t...最近在LaravelBrasil社区看到一个问题,和结果比看起来更有趣。假设您有一个具有以下实现的UsersResource:$this->id,'name'=>$this->name,'email'=>$this->email];出于某种原因,您可能希望在另一个端点上重用该资源类,但隐藏电子邮件字段。这篇文章就是告诉你如何实现这一点。如果您不知道什么是API资源,请查看我之前关于此的文章。API资源的第一印象具有嵌套关系的API资源1-初始化项目有趣的东西从第3节开始。删除数据库设置并继续使用SQLiteDB_CONNECTION=sqlite设置项目times(20)->create();quit2-routing确保在api.php文件中创建一个路由。Route::apiResource('/users','UsersController');3-控制器控制器代表所需的目的地。在这个例子中,假设在用户列表中,我们只想要所有用户的名字,而在用户显示中,我们只想隐藏电子邮件地址。paginate())->hide(['id','电子邮件']);}/***显示一个用户。**@paramUser$user*@return\Illuminate\Http\Response*/publicfunctionshow(User$user){returnUsersResource::make($user)->hide(['id']);为此,我们需要UsersResourceCollection和UsersResource来了解如何处理隐藏调用。4-UsersResource类让我们从show方法开始。UsersResource::make将返回UsersResource对象。因此,我们应该揭开存储我们要从响应中删除的键的隐藏的神秘面纱。filterFields(['id'=>$this->id,'name'=>$this->姓名,'电子邮件'=>$this->电子邮件]);}/***设置应该被过滤掉的键。**@paramarray$fields*@return$this*/publicfunctionhide(array$fields){$this->withoutFields=$fields;返回$这个;}/***删除过滤的键。**@param$array*@return数组*/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类实现了item集合中的index方法,我们需要使以下修改:(1)确保UsersResource::collection返回UsersResourceCollection实例(2)在UsersResourceCollection上公开隐藏方法(3)将隐藏字段传递给UsersResource关于(1),我们只需要覆盖UsersResource收集=__CLASS__;});}/***@vararray*/protected$withoutFields=[];/***将资源转换为数组。*将资源转换为数组**@param\Illuminate\Http\Request*@returnarray*/publicfunctiontoArray($request){return$this->filterFields(['id'=>$this->id,'name'=>$this->name,'email'=>$this->email]);}/***设置应该被过滤掉的键。*设置需要隐藏过滤Droppedkeys**@paramarray$fields*@return$this*/publicfunctionhide(array$fields){$this->withoutFields=$fields;返回$这个;}/***删除过滤的键。*移除隐藏键**@param$array*@returnarray*/protectedfunctionfilterFields($array){returncollect($array)->forget($this->withoutFields)->toArray();}}关于(2)和(3)我们需要修改UsersResourceCollection文件。让我们公开hide方法并使用隐藏字段处理集合.processCollection($request);}publicfunctionhide(array$fields){$this->withoutFields=$fields;返回$这个;}/***在处理集合时将要隐藏的字段发送到UsersResource。*将隐藏字符段通过UsersResource处理集合**@param$request*@returnarray*/protectedfunctionprocessCollection($request){return$this->collection->map(function(UsersResource$resource)use($request){返回$resource->hide($this->withoutFields)->toArray($r请求);})->全部();}}就这么简单!现在我们访问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资源,因为很可能把简单的事情变得复杂,所以在请求的时候隐藏一些特定的字段更简单也更合理。
