godruoyi/dingo-api-helper
Dingo api response helper.
说明
默认情况下,Dingo/api 提供的 response 需要配置一大堆信息,包括
1、Adapter 的配置
$app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
$fractal = new League\Fractal\Manager;
$fractal->setSerializer(new League\Fractal\Serializer\ArraySerializer);
return new Dingo\Api\Transformer\Adapter\Fractal($fractal);
});
并且默认的 ArraySerializer 返回格式比较奇怪,如返回资源集合时,ArraySerializer 的返回格式如下:
{
"data": [
{
"id": 1,
"name": "lianbo"
}
]
}
在最外层包含一层无用 data
2、Transformer 的指定
默认情况下在 controller 在中通过 dingo response 返回数据时,必须指定 Transformer 的位置;
class ExampleController extends BaseController
{
public function __invoke()
{
$users = User::all();
return $this->response->collection($users, new UserTransformer);//每次都要手动指定
}
}
若不指定 Transfoemr 的位置,你将会得到一个参数不匹配的错误。
{
"message": "Too few arguments to function Dingo\\Api\\Http\\Response\\Factory::collection(), 1 passed in Controller.php on line 16 and at least 2 expected",
"status_code": 500
}
这显然不是我们想要的结果。我们希望框架能自动处理 Transformer 的位置,也能够手动指定。
return $this->response->item($user);
return $this->response->item($user, new \Other\UserDetailTransformer);
3、无法自定义错误码
从上面可以看到,dingo/api 返回的错误响应无法自定义错误码,错误信息里只含有标准的 http 状态码,这显示是不够用的。
虽然他也提供了 errorFormat 配置,但该配置的 code 错误码实际调用的是 $exception->getCode(),在实际工作中并没什么用。
综上,我们开发了一个新的 Package 来解决以上问题,并提供了如
- 异常转换
- 自定义错误码
- 标准的 restful 支持
- 适时的禁用预加载
等功能,希望您的喜欢 ❤️❤️❤️
安装
$ composer require godruoyi/dingo-api-helper -vvv
使用
Laravel 版本小于 5.5 时,需要手动注册 Provider。
Godruoyi\DingoApiHelper\ServiceProvider::class,
配置成功后,即可在你的 controller 使用:
use Dingo\Api\Routing\Helpers;
class ExampleController extends Controller
{
use Helpers;
public function __invoke()
{
$users = User::all();
return $this->response->collection($users);
// return $this->response->collection($users, new OtherTransformer);
}
}
默认的 Transformer 文件在 App/Transformers 下,你可通过修改方法的第二个参数指定 transformer 的位置。
public function __invoke(Request $request)
{
$user = User::find($request->id);
return $this->response->item($user, new \Other\UserDetailTransformer);
}
可用的方法列表
成功响应方法列表
// 响应一个 Arrayable 的数据
return $this->response->created($content = null);
return $this->response->success($content = null);
return $this->response->array($content = null);
return $this->response->accepted($content = null);
// 无内容响应
return $this->response->noContent();
// 返回一个集合
return $this->response->collection($collection);
// 返回单个详情
return $this->response->item($item);
// 返回分页数据
return $this->response->paginator($paginator);
错误响应方法列表
// 一个自定义消息和状态码的普通错误。
return $this->response->error('This is an error.', 404, $errorCode = null);
// 一个没有找到资源的错误,第一个参数可以传递自定义消息。
return $this->response->errorNotFound($message = 'Not Found', $errorCode = null);
// 一个 bad request 错误,第一个参数可以传递自定义消息。
return $this->response->errorBadRequest($message = 'Bad Request', $errorCode = null);
// 一个服务器拒绝错误,第一个参数可以传递自定义消息。
return $this->response->errorForbidden($message = 'Forbidden', $errorCode = null);
// 一个内部错误,第一个参数可以传递自定义消息。
return $this->response->errorInternal($message = 'Internal error', $errorCode = null);
// 一个未认证错误,第一个参数可以传递自定义消息。
return $this->response->errorUnauthorized($message = 'Unauthorized', $errorCode = null);
更多详情请参考 https://learnku.com/docs/dingo-api/2.0.0/Responses/1446
返回格式
返回格式遵循 Restful api 设计规范,具体如下。
Success Response
1、获取单个资源详情(item)
{
"id": 1,
"username": "godruoyi",
"age": 88,
}
2、获取资源集合(collection)
[
{
"id": 1,
"username": "godruoyi",
"age": 88,
},
{
"id": 2,
"username": "foo",
"age": 88,
}
]
3、额外的媒体信息(paginator)
{
"data": [
{
"id": 1,
"avatar": "https://lorempixel.com/640/480/?32556",
"nickname": "fwest",
"last_logined_time": "2018-05-29 04:56:43",
"has_registed": true
},
{
"id": 2,
"avatar": "https://lorempixel.com/640/480/?86144",
"nickname": "zschowalter",
"last_logined_time": "2018-06-16 15:18:34",
"has_registed": true
}
],
"meta": {
"pagination": {
"total": 101,
"count": 2,
"per_page": 2,
"current_page": 1,
"total_pages": 51,
"links": {
"next": "http://api.example.com?page=2"
}
}
}
}
Failure Response
{"error_code":40301,"message":"权限不足"}
禁用预加载
有时候你可能想在 Transformer 中定义一些不存在的 Relation include,如:
namespace App\Transformers;
class UserTransformer extends TransformerAbstract
{
/**
* Include resources without needing it to be requested.
*
* @var array
*/
protected $defaultIncludes = ['notExistsRelacation'];
public function transform(User $user, $a)
{
}
}
由于 fractal 默认开启了预加载机制,你可能会得到一个如下的错误:
production.ERROR: Call to undefined relationship [notExistsRelacation] on model [App\Models\User]
Illuminate\\Database\\Eloquent\\RelationNotFoundException(code: 0):
Call to undefined relationship [notExistsRelacation] on model [App\Models\User].
at vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(548):
可通过禁用 Model 的预加载解决
class ExampleController extends Controller
{
use Helpers;
public function __invoke()
{
$users = User::all();
return $this->response->disableEagerLoading()->collection($users);
}
}
参考
Related Packages
Powerful PHP database abstraction layer (DBAL) with many features for database s...
Laravel Serializable Closure provides an easy and secure way to serialize closur...
Cli error handling for console/command-line PHP applications.
Version History
| Version | Released | Laravel | License |
|---|---|---|---|
| 1.0.2 | ^5.7 | | MIT | |
| 1.0.1 | ^5.7 | | MIT | |
| 1.0.0 | ^5.7 | | MIT |