从Laravel 5.5+开始,加入了API Resources这个概念。
我们先来看一下官网如何定义这个概念的:
When building an API, you may need a transformation layer that sits between your Eloquent models and the JSON responses that are actually returned to your application's users. Laravel's resource classes allow you to expressively and easily transform your models and model collections into JSON.
可能看完这个概念之后,你仍然有点不明白,毕竟这个定义说的有点含糊。
如果你熟悉使用API进行输出,构架前后端分离的网络应用,那么你应该会发现,当我们使用Eloquent从数据库中取出数据后,如果想以JSON格式进行输出,那么我们可以使用->toJson()这个方法,这个方法可以直接将我们的model序列化(这个方法从Laravel 5.1+开始就可以使用了):
$user = App\User::find(1); return $user->toJson();
使用多了,我们会发现,在model较为复杂,或者model中有很多我们API输出可能用不到的字段的情况下,toJson()仍然会忠实地帮我们把这些字段序列化出来。
这个时候,我们会想,如何将model中的某些字段隐藏起来,不输出到JSON中。另外一种情况,比如字段是password等一些敏感信息的时候,我们不希望JSON数据里包含这样的敏感信息。
要解决这个问题,我们可以在model里定义$hidden或者$visible这两个数组来进行字段的隐藏或者显示:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * 不希望在序列化中出现的字段放入该数组中 * * @var array */ protected $hidden = ['password', 'some', 'secret']; }
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * 只有在以下数组中出现的字段会被序列化 * * @var array */ protected $visible = ['first_name', 'last_name']; }
那么你可能会想,我们已经有了可以自动序列化的方法,以及可以隐藏或者显示指定字段的方法,这样不就足够了吗?
现在我们来假设一个简单的应用场景。假设我们在输出一个客户列表,里面包含了客户名字和送货地址。我们使用Customer这个model定义客户,使用ShippingAddress这个model进行定义送货地址。为了简化场景,我们的客户只有一个送货地址,所以只会出现一一对应的情况。
那么在ShippingAddress对应的数据库表shipping_addresses中,我们可能会有如下定义:
| id | country_id | province_id | city_id | address |
字段类型我就不赘述了,其中country_id、province_id以及city_id这三个外键分别对应了国家、省份以及城市表中的id。