Dingo API 移除 "data" 信封
Dingo API remove "data" envelope
有没有一种简单的方法可以从 Dingo API 响应中删除 "data" 信封。
当我使用此 Transformer 转换用户模型时:
class UserTransformer extends EloquentModelTransformer
{
/**
* List of resources possible to include
*
* @var array
*/
protected $availableIncludes = [
'roles'
];
protected $defaultIncludes = [
'roles'
];
public function transform($model)
{
if(! $model instanceof User)
throw new InvalidArgumentException($model);
return [
'id' => $model->id,
'name' => $model->name,
'email' => $model->email
];
}
/**
* Include Roles
*
* @param User $user
* @return \League\Fractal\Resource\Item
*/
public function includeRoles(User $user)
{
$roles = $user->roles;
return $this->collection($roles, new RoleTransformer());
}
我收到这样的回复:
{
data : [
"id": 102,
"name": "Simo",
"email": "mail@outlook.com",
"roles": {
"data": [
{
"id": 1
"name": "admin"
}
]
}
}
]
}
我读了一些关于 RESTful API 的文章,其中很多都说这种封装的响应不是很现代(您应该改用 HTTP Header)。
我怎样才能至少为包含禁用此行为?
谢谢
看看http://fractal.thephpleague.com/serializers/#arrayserializer。他们确切地解释了
时该怎么做
Sometimes people want to remove that 'data' namespace for items
对于那些后来遇到这个问题的人,因为我真的很难做到,我想分享一下我是如何在 API 中实现它的:
1) 创建自定义序列化程序,NoDataArraySerializer.php :
namespace App\Api\V1\Serializers;
use League\Fractal\Serializer\ArraySerializer;
class NoDataArraySerializer extends ArraySerializer
{
/**
* Serialize a collection.
*/
public function collection($resourceKey, array $data)
{
return ($resourceKey) ? [ $resourceKey => $data ] : $data;
}
/**
* Serialize an item.
*/
public function item($resourceKey, array $data)
{
return ($resourceKey) ? [ $resourceKey => $data ] : $data;
}
}
2) 设置新的Serializer。在bootstrap/app.php中添加:
$app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
$fractal = new League\Fractal\Manager;
$fractal->setSerializer(new App\Api\V1\Serializers\NoDataArraySerializer);
return new Dingo\Api\Transformer\Adapter\Fractal($fractal);
});
就是这样。
现在,在您的 UserController(例如)中,您可以像这样使用它:
namespace App\Api\V1\Controllers;
use App\Api\V1\Models\User;
use App\Api\V1\Transformers\UserTransformer;
class UserController extends Controller
{
public function index()
{
$items = User::all();
return $this->response->collection($items, new UserTransformer());
}
}
响应将如下所示:
[
{
"user_id": 1,
...
},
{
"user_id": 2,
...
}
]
或者,我要添加信封,只需要在Controller中设置resource key即可。替换:
return $this->response->collection($items, new UserTransformer());
来自
return $this->response->collection($items, new UserTransformer(), ['key' => 'users']);
响应将如下所示:
{
"users": [
{
"user_id": 1,
...
},
{
"user_id": 2,
...
}
]
}
YouHieng 解决方案的一个补充。在 Laravel 5.3 及更高版本中注册 NoDataArraySerializer
的首选方法是编写自定义 ServiceProvider
并将逻辑添加到 boot()
方法而不是 bootstrap/app.php
文件中.
例如:
php artisan make:provider DingoSerializerProvider
然后:
public function boot(){
$this->app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
$fractal = new League\Fractal\Manager;
$fractal->setSerializer(new App\Http\Serializers\NoDataArraySerializer());
return new Dingo\Api\Transformer\Adapter\Fractal($fractal);
});
}
有没有一种简单的方法可以从 Dingo API 响应中删除 "data" 信封。
当我使用此 Transformer 转换用户模型时:
class UserTransformer extends EloquentModelTransformer
{
/**
* List of resources possible to include
*
* @var array
*/
protected $availableIncludes = [
'roles'
];
protected $defaultIncludes = [
'roles'
];
public function transform($model)
{
if(! $model instanceof User)
throw new InvalidArgumentException($model);
return [
'id' => $model->id,
'name' => $model->name,
'email' => $model->email
];
}
/**
* Include Roles
*
* @param User $user
* @return \League\Fractal\Resource\Item
*/
public function includeRoles(User $user)
{
$roles = $user->roles;
return $this->collection($roles, new RoleTransformer());
}
我收到这样的回复:
{
data : [
"id": 102,
"name": "Simo",
"email": "mail@outlook.com",
"roles": {
"data": [
{
"id": 1
"name": "admin"
}
]
}
}
]
}
我读了一些关于 RESTful API 的文章,其中很多都说这种封装的响应不是很现代(您应该改用 HTTP Header)。
我怎样才能至少为包含禁用此行为?
谢谢
看看http://fractal.thephpleague.com/serializers/#arrayserializer。他们确切地解释了
时该怎么做Sometimes people want to remove that 'data' namespace for items
对于那些后来遇到这个问题的人,因为我真的很难做到,我想分享一下我是如何在 API 中实现它的:
1) 创建自定义序列化程序,NoDataArraySerializer.php :
namespace App\Api\V1\Serializers;
use League\Fractal\Serializer\ArraySerializer;
class NoDataArraySerializer extends ArraySerializer
{
/**
* Serialize a collection.
*/
public function collection($resourceKey, array $data)
{
return ($resourceKey) ? [ $resourceKey => $data ] : $data;
}
/**
* Serialize an item.
*/
public function item($resourceKey, array $data)
{
return ($resourceKey) ? [ $resourceKey => $data ] : $data;
}
}
2) 设置新的Serializer。在bootstrap/app.php中添加:
$app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
$fractal = new League\Fractal\Manager;
$fractal->setSerializer(new App\Api\V1\Serializers\NoDataArraySerializer);
return new Dingo\Api\Transformer\Adapter\Fractal($fractal);
});
就是这样。
现在,在您的 UserController(例如)中,您可以像这样使用它:
namespace App\Api\V1\Controllers;
use App\Api\V1\Models\User;
use App\Api\V1\Transformers\UserTransformer;
class UserController extends Controller
{
public function index()
{
$items = User::all();
return $this->response->collection($items, new UserTransformer());
}
}
响应将如下所示:
[
{
"user_id": 1,
...
},
{
"user_id": 2,
...
}
]
或者,我要添加信封,只需要在Controller中设置resource key即可。替换:
return $this->response->collection($items, new UserTransformer());
来自
return $this->response->collection($items, new UserTransformer(), ['key' => 'users']);
响应将如下所示:
{
"users": [
{
"user_id": 1,
...
},
{
"user_id": 2,
...
}
]
}
YouHieng 解决方案的一个补充。在 Laravel 5.3 及更高版本中注册 NoDataArraySerializer
的首选方法是编写自定义 ServiceProvider
并将逻辑添加到 boot()
方法而不是 bootstrap/app.php
文件中.
例如:
php artisan make:provider DingoSerializerProvider
然后:
public function boot(){
$this->app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
$fractal = new League\Fractal\Manager;
$fractal->setSerializer(new App\Http\Serializers\NoDataArraySerializer());
return new Dingo\Api\Transformer\Adapter\Fractal($fractal);
});
}