当前位置: 首页 > news >正文

在 Laravel 中动态隐藏 API 字段

最近项目有多个不同类型前端,所以在给api返回数据的时候需要隐藏某些字段 之前看了一篇文章在 Laravel 中动态隐藏 API 字段觉得还是有点不方便,所以就自己弄了一个。 目前实现了三个方法

  1. 设置隐藏的自动
  2. 设置显示的字段
  3. 设置类型(在toArray里面判断类型返回相应的数据)

Resource 实现

首先看Resource如何实现 自定义一个BaseResource继承Resource。。额!直接上代码吧

class BaseResource extends Resource
{
    protected $withoutFields = [];

    private $hide = true;

    protected $type = 'default';

    public function type(string $request)
    {
        $this->type = $request;
        return $this;
    }

    public function hide(array $fields)
    {
        $this->withoutFields = $fields;
        return $this;
    }

    public function show(array $fields)
    {
        $this->withoutFields = $fields;
        $this->hide = false;
        return $this;
    }

    protected function filterFields($array)
    {
        if (!$this->hide) {
            return collect($array)->only($this->withoutFields)->toArray();
        }
        return collect($array)->except($this->withoutFields)->toArray();
    }
}
复制代码

在相应的Resource从原来的Resource继承BaseResource。继续上代码

class Channel extends BaseResource
{
    public function toArray($request)
    {
        return $this->filterFields([
            'id' => $this->id,
            'name' => $this->name,
            'cover' => $this->cover,
			'user'=>[
                'nickname'=>'small-dog',
                'avatar'=>'xxx'
            ]
        ]);
    }
}
复制代码

如何使用??很简单啦

$channel = Channel::find(1);
ChannelResource::make($channel)->hide(['name','user.nickname']);//支持 . 来隐藏多维数组
复制代码

ResourceCollection 实现

这个也差不多,就一点细微的差别 定义一个BaseResourceCollection继承ResourceCollection。。额!直接上代码吧

class BaseResourceCollection extends ResourceCollection
{
    protected $withoutFields = [];
    private $hide = true;
    protected $type = 'default';
    public function type(string $request)
    {
        $this->type = $request;
        return $this;
    }
    public function hide(array $fields)
    {
        $this->withoutFields = $fields;
        return $this;
    }
    public function show(array $fields)
    {
        $this->withoutFields = $fields;
        $this->hide = false;
        return $this;
    }
    public function toArray($request)
    {
        return [
            'data' => $this->collection->map(function ($item) {
                if (!$this->hide) {
                    return collect($item)->only($this->withoutFields)->all();
                }
                return collect($item)->except($this->withoutFields)->all();
            }),
            'meta' => $this->when(!empty($this->pageMeta()), $this->pageMeta())
        ];
    }
    //定义这个方法主要用于分页,当用josn返回的时候是没有 links 和 meta 的
    public function pageMeta()
    {
        try {
            return [
                'current_page' => $this->resource->currentPage(),
                'last_page' => $this->resource->lastPage(),
                'per_page' => $this->resource->perPage(),
                'total' => $this->resource->total(),
            ];
        } catch (\BadMethodCallException $exception) {
            return [];
        }
    }
}
复制代码

自己的Collection继承BaseResourceCollection

class ChannelCollection extends BaseResourceCollection
{
}
复制代码

toArray都可以省了,哈哈哈!!! 使用方法

$channel = Channel::query()->where('user_id', $user->id)->orderByDesc('id');
$page = $channel->paginate(10);//当用get的时候是没有meta这个字段的
$data['list'] = ChannelCollection::make($page)->hide(['name','user.nickname']);
复制代码

type 的用法

最后说一个设置类型的作用,一个资源文件要处理不同类型的数据,比如一个是给APP的,一个是给商家后台的

public function toArray($request)
    {
        if ($this->type == 'edit') {
            return $this->filterFields([
                'id' => hashid_encode($this->id),
            ]);
        }
        return $this->filterFields([
            'id' =>$this->id,
        ]);
    }
复制代码

然后在使用的时候

$channel = Channel::find(1);
ChannelResource::make($channel)->type('edit')->hide(['name','user.nickname']);//支持 . 来隐藏多维数组
复制代码

总结

本文目标是让Resource类通过隐藏一些在其他接口允许暴露的字段从而变得更加灵活,可能会有问题,目前我还没遇到,今天才弄出来的~~~

如果有类型需求的小伙伴用了这个发现问题可以讨论哦~~~

相关文章:

  • 采购与供应商管理:如何突破传统模式
  • GDB调试技巧:gdb at pid无法调试的问题
  • [CERC2017]Cumulative Code
  • 使用OpenCV+C++将Gif文件分解并且转换为视频文件
  • webTest-----webUI自动化框架
  • 高通无人机新技术,深度学习把控飞行安全
  • 比特币价格再创新高,当年的0.3美分已经变为7290万美元
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 2018 Web 开发者最佳学习路线之less
  • Logistic 回归算法及Python实现
  • 「镁客·请讲」Vincross徐凯强:从运动控制技术出发,为机器人开发者提供便捷的开发平台...
  • centos6中了挖矿***的解决办法
  • 数据库乐观锁的配置
  • 方案
  • 安装oracle出现环境不满足最低要求
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • 2017-09-12 前端日报
  • Angular 响应式表单 基础例子
  • const let
  • Git初体验
  • iOS 系统授权开发
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • Java 多线程编程之:notify 和 wait 用法
  • JavaScript/HTML5图表开发工具JavaScript Charts v3.19.6发布【附下载】
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • Laravel Telescope:优雅的应用调试工具
  • Object.assign方法不能实现深复制
  • v-if和v-for连用出现的问题
  • win10下安装mysql5.7
  • windows下使用nginx调试简介
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 什么是Javascript函数节流?
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (Redis使用系列) SpirngBoot中关于Redis的值的各种方式的存储与取出 三
  • (二)fiber的基本认识
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (附源码)计算机毕业设计ssm高校《大学语文》课程作业在线管理系统
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .form文件_一篇文章学会文件上传
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .net利用SQLBulkCopy进行数据库之间的大批量数据传递
  • .NET企业级应用架构设计系列之应用服务器
  • .Net下C#针对Excel开发控件汇总(ClosedXML,EPPlus,NPOI)
  • /bin/bash^M: bad interpreter: No such file ordirectory
  • @vue/cli脚手架
  • []sim300 GPRS数据收发程序
  • [2019/05/17]解决springboot测试List接口时JSON传参异常