从零开始系列-Laravel编写api服务接口:2.Dingo封装

Laravel框架
413
0
0
2022-04-12

前言

文档:《Dingo API 3.x 中文文档》

不用 dingo 完全可以满足所有需求,但是用了 dingo 更方便,特别是 transformer 和一些函数非常好用,下面简单介绍一下安装和使用,注意:Laravel 新版可以不用 dingo,直接用 resource 替代,具体可见文档 Eloquent: API 资源

安装

最新版本为 dingo3.0.0

composer require dingo/api

复制配置文件

php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"

复制到.env 文件下

# dingo
API_STANDARDS_TREE=prs # The personal tree (prs) is primarily meant for projects that are not distributed commerically.
API_SUBTYPE=homestead # Your subtype is typically a short name of your application or project, all lowercase.You can configure this in your .env file. 
API_PREFIX=api # If you've ever worked with an API you'll know that most are served from either a subdomain or under a prefix. A prefix or subdomain is required, but only one. Avoid putting a version number as your prefix or subdomain as versioning is handled via the Accept header.
API_VERSION=v1 # This version is the default version of your API and is used as a fallback in several circumstances whenever a version is not supplied. This version is also used
API_DEBUG=true 
以下代码复制到 app/Providers/AppServiceProvider 的 boot 方法里面
$this->app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
      $fractal = new \League\Fractal\Manager;
      $fractal->setSerializer(new \League\Fractal\Serializer\JsonApiSerializer); // 设置响应器(new ArraySerializer();)
      return new \Dingo\Api\Transformer\Adapter\Fractal($fractal);
});

5. 路由如:

// laravel 默认路由
Route::middleware('auth:api')->get('/user', function (Request $request) {
  return $request->user();
});

if ('local' === config('app.env')) {
  Route::any('sms', '\\Toplan\\Sms\\SmsController@getInfo');
}
// 配置dingo路由
$api = app('Dingo\Api\Routing\Router');
// 默认Accept application/prs.hospital.v1+json
$api->version('v1', ['namespace' => 'App\Http\Controllers\Api', 'middleware' => ['bindings']], function ($api) {
  //后台接口
  $api->group(['as' => 'admin', 'prefix' => 'admin', 'namespace' => 'Admin', 'middleware' => []], function ($api) {
    // 登录获取token
    $api->post('authorizations', 'AuthorizationsController@store')
      ->name('.authorizations.store');
    // 刷新生成新的token
    $api->get('refresh_token', 'AuthorizationsController@refresh')
      ->name('.authorizations.refresh');
    // 退出登录
    $api->get('log_out', 'AuthorizationsController@logOut')->name('.authorizations.logout');
    //需要登录后的接口
    $api->group(['middleware' => ['auth:admin', 'bindings']], function ($api) {

    });
  }
});

6. 拦截 dingo 异常 例如:

API::error(function (ValidationException $exception) {
      $errors = $exception->errors();
      return response()->json(['message' => $errors->first(), 'status_code' => 422], 422);
    });
API::error(function (BadRequestException $exception) {
  $errors = $exception->getMessage();
  return response()->json(['data' => $exception->data, 'message' => $errors, 'status_code' => 422], 422);
});
// dingo 表单验证自定义异常
API::error(function (ValidationHttpException $exception) {
  $errors = $exception->getErrors();
  return response()->json(['message' => $errors->first(), 'status_code' => 422], 422);
});
API::error(function (InvalidRequestException $exception) {
  return response()->json(['message' => $exception->getMessage(), 'status_code' => 422], 422);
});
API::error(function (\InvalidArgumentException $exception) {
  return response()->json(['message' => $exception->getMessage(), 'status_code' => 422], 422);
});

API::error(function (ModelNotFoundException $e) {
  $data = config('app.debug') ? [
    'message'  => $e->getMessage(),
    'exception' => get_class($e),
    'file'   => $e->getFile(),
    'line'   => $e->getLine(),
    'trace'   => collect($e->getTrace())->map(function ($trace) {
      return Arr::except($trace, ['args']);
    })->all(),
  ] : ['message' => '资源未找到'];
  return response()->json($data, 422);
});