👊一个简单的方式去使用你的 dingo/api
👊一个简单的方式去使用你的 dingo/api
PHP 其它杂项
共8Star
详细介绍
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);
}
}