换个方式实现API Resource以提高开发效率

因为看了 API 资源 产生的想法,觉得好是好,写起来稍微有些麻烦,就改了改,用的还挺舒服。

简单实现

Class User extends Model
{
    ...

    public function roles()
    {
        return $this->hasMany(Role::class);
    }

    public function phone()
    {
        return $this->hasOne(Phone::class);
    }

    public function toArray()
    {
        return [
            'user_id' => $this->id,
            'user_name' => $this->name,
            'user_phone' => (object) $this->phone,  // 空数据Json返回 {} 而不是null 保持数据类型一致
            'user_roles' => $this->roles->map(function($item){
                return $item->toArray();
            })
        ];
    }
}

// 单个返回
User::find(1)->toArray();

// 列表
User::with(['roles', 'phone'])->all()->map(function($item){
    return $item->toArray();
});

这样写有什么好处呢,保证了所有API在返回用户的时候数据一致,且新增字段只需要更改toArray则所有User的数据都会同步修改,而且最重要的是快啊。
当然里面还有一些小细节,比如说如果是 belongsTo 则需根据一对一或是一对多 判断是否为null之后的处理会稍微麻烦一些,毕竟 Java 或者 IOS 这样的强类型语言,如果他们兼容最的不好,我们数据结构变了就会导致他们崩溃。

api
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5

复杂场景下你这个就影响别的范围了

3年前 评论

@yangjisen 你可以写2个toXXX,一个列表用,一个详情用,至于复杂的情况,可以在循环里做一些逻辑处理,复杂情况,基本都不会通用,上文只是提供一个思路罢了,我用了好几年了感觉挺好的。

map(function($item) use ($foo){
    return array_merge($item->toArray, ['foo' => $foo->bar]);
});
3年前 评论

写在 Resource 里不是更方便吗,而且 resource 和模型并不是强关联(?)的 你可以针对一个 model 写多个不同的 resource 来针对不同的场景,关联的时候也很方便

3年前 评论
Adachi (楼主) 3年前
Epona

你这个和Resource没什么区别,而且,有些resource的封装好的方法你也没法用。

3年前 评论
Adachi (楼主) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!