记录一次 Lumen 集成 Dingo

1.安装 Dingo

以下步骤建立在已经安装好 Lumen 和 composer 安装好 Dingo

1.注册服务,在 bootstrap/app.php 中注册

$app->register(Dingo\Api\Provider\LumenServiceProvider::class);

2.添加路由文件routes/api.php,在 bootstrap/app.php 引入路由

$app->router->group([
    'namespace' => 'App\Http\Controllers',
], function ($router) {
    $api = app('Dingo\Api\Routing\Router');
    require __DIR__.'/../routes/web.php';
    require __DIR__.'/../routes/api.php';
});

3.写 demo 测试

// bootstrap/app.php 放开下面代码的注释
$app->withFacades();
$app->withEloquent();

// routes/api.php 写个路由
$api->version('v1', function ($api) {
    $api->get('/user', 'App\Api\Controllers\UserController@user');
    $api->get('/users', 'App\Api\Controllers\UserController@users');
});

// App\Api\Controllers\ 目录下(目录不存在新建)新建 UserController 控制器

namespace App\Api\Controllers;

use Dingo\Api\Routing\Helpers;
use App\Api\Transformers\UserTransformer;

class UserController
{
    use Helpers;

    public function user()
    {
        $user = User::find(1);
        return $this->response->item($user, new UserTransformer());
    }

    public function users()
    {
        $user = User::where('id', '>', 0)->get();
        return $this->response->collection($user, new UserTransformer());
    }

}

// 新建 UserTransformer.php
namespace App\Api\Transformers;

use App\Api\Models\User;
use League\Fractal\TransformerAbstract;

class UserTransformer extends TransformerAbstract
{
    protected $availableIncludes = [];
    protected $defaultIncludes = [];

    public function transform(User $model)
    {
        return [
            'id' => $model->id,
            'name' => $model->nickname
        ];
    }

}
  • 访问 demo.com/user
{
    "data": {
        "id": 123086,
        "name": "Tommy Dai"
    }
}
  • 访问 demo.com/users
{
    "data": [
        {
            "id": 123086,
            "name": "Tommy Dai"
        },
        {
            "id": 137540,
            "name": "Tommy Dai"
        }
    ]
}

2.解决痛点

  • 所有返回数据都在 data 字段内
// bootstrap/app.php 文件中放开注释(注意这个要放在注册 Dingo的下面)
$app->register(Dingo\Api\Provider\LumenServiceProvider::class);
$app->register(App\Providers\AppServiceProvider::class);

// AppServiceProvider 内添加 boot方法
public function boot()
{
    $this->app['Dingo\Api\Transformer\Factory']->setAdapter(function ($app) {
        $fractal = new \League\Fractal\Manager;
        $fractal->setSerializer(new \App\Api\BaseClasses\DataArraySerializer);
        return new \Dingo\Api\Transformer\Adapter\Fractal($fractal);
    });
}

// 新建 \App\Api\BaseClasses\DataArraySerializer.php ,没有目录的话需要新建目录
namespace App\Api\BaseClasses;


use League\Fractal\Serializer\ArraySerializer;

class DataArraySerializer extends ArraySerializer
{
    public function collection($resourceKey, array $data)
    {
        return $resourceKey ? [$resourceKey => $data] : $data;
    }

    public function item($resourceKey, array $data)
    {
        return $resourceKey ? [$resourceKey => $data] : $data;
    }
}
  • 好了,重新访问 demo.com/user 和 demo.com/users
{
    "id": 123086,
    "name": "Tommy Dai"
}
[
    {
        "id": 123086,
        "name": "Tommy Dai"
    },
    {
        "id": 137540,
        "name": "Tommy Dai"
    }
]

3.小试牛刀

  • UserTransformer.php 文件加入动态解析的字段和方法
// 用户模型 一对一 关联用户角色
protected $availableIncludes = ['role'];

public function includeRole(User $user)
{
    return $this->item($user->role, new RoleTransformer());
}
  • 访问 demo.com/user 和 demo.com/user?include=role
// demo.com/user
{
    "id": 123086,
    "name": "Tommy Dai"
}

// demo.com/user?include=role
{
    "id": 123086,
    "name": "Tommy Dai"
    "role": {
        "id": 12,
        "name": "二级管理员",
    }
}

$availableIncludes 可以填入多个动态字段。暂时就这么多,以后用到更多其它功能在完善此文档

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 2

数据里含有data下标有更优雅的解决方案

如果你不使用资源键参数,可以省略空数组,直接把回调方法作为第三个参数。

return $this->collection($users, new UserTransformer, function ($resource, $fractal) {
    $fractal->setSerializer(new CustomSerializer);
});
4年前 评论

我记得文档里说路由里整闭包就不会缓存。dingo并不好用,自己封装个json返回,少整这鬼玩意

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!