Laravel 不使用第三方包,实现 API 功能。
参考:
生成资源
1 | # 生成 User资源 |
app/Http/Resources/User.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources\Book as BookResource;
class User extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
// $this 代表 User 实例
return [
'id' => $this->id,
'name' => $this->name,
'email' => $this->phone,
];
}
}
资源的使用
routes/api.php
1 | ... |
单个资源
资源集合的使用
1 | ... |
自定义资源集合
app/Http/Resources/BookCollection.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;
class BookCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function toArray($request)
{
return [
'data'=>$this->collection,
'link'=>'link-value'
];
}
}
自定义资源集合
资源关联
直接关联
User和Book关联,一个读者有多本书。
app/Models/User.php1
2
3
4
5
6...
public function books()
{
return $this->hasMany(Book::class);
}
app/Http/Resources/User.php
1 | ... |
routes/api.php1
2
3
4
5...
Route::get('/info/related', function () {
return new UserResource(App\Models\User::find(1));
});
关联的操作放在 Resource中完成,路由中没有参与。
条件关联
app/Http/Resources/User.php
1 | ... |
routes/api.php1
2
3
4
5...
Route::get('/info/condition', function () {
return new UserResource(App\Models\User::find(1)->load('books'));
});
关联的操作路由和 Resource中都有出现。路由中取消load(‘books’),响应中不会出现book数据,符合条件关联。
Include机制
如果客户端只是显示一下所有话题的标题,但是接口却返回了所有相关的数据,不仅做了额外的查询,还增加了响应的数据.
最好的做法应该是客户端想要什么,我们就返回什么资源的数据,客户端应该提供参数,告诉接口是否需要相关的其他资源。
1 | $ composer require spatie/laravel-query-builder |
扩展包的使用
扩展包针对的是资源集合。
app/Http/Controllers/Api/UsersController.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
namespace App\Http\Controllers\Api;
use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Spatie\QueryBuilder\QueryBuilder;
use Spatie\QueryBuilder\AllowedFilter;
use App\Http\Resources\User as UserResource;
class UsersController extends Controller
{
// allowedIncludes('books') model中定义的books()方法。
// allowedFilters过滤器,例如 ’name',模糊搜索对应的 name值
public function index()
{
$users = QueryBuilder::for(User::class)
->allowedIncludes('books')
->allowedFilters([
'name'
])
->paginate();
return UserResource::collection($users);
}
}
app/Http/Resources/User.php
1 |
|
routes/api.php1
2
3
4
5...
Route::namespace('Api')->group(function (){
Route::get('/users/','UsersController@index');
});
Include机制