Lumen 使用踩点之 Dingo

公司有个产品准备使用Laravel或者Lumen,同时希望能够使用RESTful API进行设计开发,来减少对移动端和PC端的功能适配,同样是新手,近来调试配置中也遇到了不少问题,记录些个人理解供大家参考交流,欢迎拍砖:)

Dingo作为第三方API开发组件,针对laravel和lumen都提供了适配的serviceprovider。
ApiServiceProvider作为2个框架服务的基类,注册了用于API处理的dispatcher,auth,response,exception等基本功能。

  • Dingo API路由如何处理

    使用Dingo创建的API路由并没有被存储在lumen主容器的routes中,而是被置于Dingo的dispatcher中。当框架中以注册的路由无法处理外部request时,就将该request扔进所有middleware组成的pipeline中进行处理,其中dingo的request就被添加到Lumen的首个中间件队列上,因此该API请求并可通过通过dispatcher进行分发处理。

    /**
     * Add the request middleware to the beginning of the middleware stack on the
     * Lumen application instance.
     *
     * @param \ReflectionClass $reflection
     *
     * @return void
     */
    protected function addRequestMiddlewareToBeginning(ReflectionClass $reflection)
    {
        $property = $reflection->getProperty('middleware');
        $property->setAccessible(true);

        $middleware = $property->getValue($this->app);

        array_unshift($middleware, 'Dingo\Api\Http\Middleware\Request');

        $property->setValue($this->app, $middleware);
        $property->setAccessible(false);
    }
  • API配置和访问

    在laravel中使用通过给API_DOMAIN赋值可以实现API专有子域名,比如可以使用api.test.app来请求如下的api服务器

    'domain' => env('API_DOMAIN', 'api.test.app'),
    

但是在lumen中配置后无法访问,需要使用prefix来区分API请求。

原因是Lumen 没有使用 Symfony 的路由模块, 而是采用了速度更加快的 nikic/fast-route。请参考
而fast-route并没有诸如子域名等高级功能。

Laravel中可以使用artisian的api:routes来查看所有的路由是否建立成功,以及对应的映射关系和URL,比如

+----------------+-------------------------------+------+--------------------------------------------------------------------+------------+-----------+----------+
| Domain         | URI                           | Name | Action                                                             | Version(s) | Protected | Scope(s) |
+----------------+-------------------------------+------+--------------------------------------------------------------------+------------+-----------+----------+
| api.lvtest.app | GET|HEAD /v1                  |      | App\Http\Controllers\Api\V1\PerformanceController@text_test        | v1         | No        |          |
| api.lvtest.app | GET|HEAD /v1/text_test        |      | App\Http\Controllers\Api\V1\PerformanceController@text_test        | v1         | No        |       

但是Lumen中缺少该命令。查看ApiServiceProvider时发现该被注册时使用commands方法可以创建命令,尝试主动创建时发现一些依赖文件不存在,因此无法实现。待后面研究下artisan再搞

        $this->commands([
            'Dingo\Api\Console\Command\Docs',
            //'Dingo\Api\Console\Command\Routes'  // 无法创建,因为缺少依赖的illuminate组件中的route文件
        ]);

        if (class_exists('Illuminate\Foundation\Application', false)) {
            $this->commands([
                'Dingo\Api\Console\Command\Cache',
                'Dingo\Api\Console\Command\Routes'
            ]);
        }
  • API用户身份验证

    Lumen虽然没有像laravel一样提供了auth相关的更多服务,但是保留了默认的2种认证驱动,即Eloquent和Database。可在api.php中进行配置修改。

    Eloquent驱动中需要指定AUTH_MODEL为一个实现了AuthenticatableContract的模型,可以参考laravel的User模型。

    Database驱动中需要指定AUTH_TABLE,且该表属于database中默认的DB_CONNECTION数据库

    为了对API进行验证,Dingo自带了HTTP Basic鉴权功能,同时也提供了JWT和OAuth2的验证接口。这里主要尝试了Basic和JWT方法。

通过在api.php中配置auth字段可以声明需要使用的认证服务者,比如

    'auth' => [
        'basic' => function ($app) {
            return new Dingo\Api\Auth\Provider\Basic($app['auth']);
        },        
        'jwt' => function ($app) {
            return new Dingo\Api\Auth\Provider\JWT($app[‘Tymon\JWTAuth\JWTAuth']);
        },
    ],

指定了Basic和JWTAuth两种方式,因此在lumen中会按照顺序对所需的request进行认证处理,直到成功为止。(在laravel中测试如果增加middleware时指定了provider,则会直接采用对应的认证服务处理)

当前使用MySQL进行2种驱动的验证都可以,使用mongodb还有部分问题未解决。

本帖已被设为精华帖!
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5
(= ̄ω ̄=)··· 暂无内容!

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