Laravel 基于remote model 思想实现快速服务化(入门篇)

快速预览#

安装 laravel5.5 - laravel8 之间的版本,然后安装快速服务化的 package

## 必须使用composer2版本
composer require windawake/laravelremodel dev-master

首先执行命令 php artisan laravelremodel:example-models./vendor/windawake/laravelremodel/examples/Models 目录下面的 OrderDetailRemote.php、OrderRemote.php、 ProductRemote.php 三个文件复制到 app 文件夹下面。

php artisan laravelremodel:example-models

laravel58
├── app
│ ├── Console
│ │ └── Kernel.php
│ ├── Exceptions
│ │ └── Handler.php
│ ├── Http
│ │ ├── Controllers
│ │ ├── Kernel.php
│ │ └── Middleware
│ ├── Models
│ │ ├── OrderDetailRemote.php
│ │ ├── OrderRemote.php
│ │ └── ProductRemote.php

然后创建 sqlite 的数据库文件 test.db

php ./vendor/windawake/laravelremodel/examples/sqlite/build.php

phpunit.xml 增加 sqlite 的配置并且增加 testsuite Remote

<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
         bootstrap="vendor/autoload.php"
         colors="true">
    <testsuites>
        ......
        <testsuite name="Remote">
                <directory>./vendor/windawake/laravelremodel/tests</directory>
        </testsuite>
    </testsuites>
    <php>
        ......
        <server name="DB_CONNECTION" value="sqlite"/>
        <server name="DB_DATABASE" value="./test.db"/>
    </php>
</phpunit>

最后运行测试命令 ./vendor/bin/phpunit --testsuit=Remote
运行结果如下所示,18 个 orm 例子测试通过。

root@DESKTOP-VQOELJ5:/web/linux/php/laravel/laravel58# ./vendor/bin/phpunit --testsuit=Remote
PHPUnit 7.5.20 by Sebastian Bergmann and contributors.

..................                                                18 / 18 (100%)

Time: 208 ms, Memory: 20.00 MB

OK (18 tests, 21 assertions)

功能特性#

  1. app 后端的代码不需要重构,渐进式地跟业务基础服务接口对接。
  2. 基础服务可拆解,可组合,可回退。
  3. 支持懒加载,避免了 n+1 查询 api。
  4. 支持连表,联表,原生 sql 查询,聚合查询,子查询等等,laravel orm 特性几乎全部可以使用。
  5. 使用了 laravel 服务容器写法,所以 query 编译器,分布式事务方法可以自定义。(推荐分布式事务组件)。
  6. 支持接入 GraphQL API(开发中)

原理解析#

remote model 是远程数据模型的意思。基础服务的 api 接口被封装成 ORM。app 后端的 model 只是虚拟的 model,是业务基础服务 model 的一个镜像。

例如紫色的 ProductModel 是镜像,但是 OrderLogic 使用它跟使用白色的 ProductModel 几乎一样。
这样子做有什么好处呢?可以复用 laravel model 的所有特性。因为现在很多 package 包针对 model 做了很多新功能,实现 model 增强功能,使用它们可以提高开发效率和排错效率,代码更加简洁强悍。

如何使用#

新建一个 ProductRemote 类继承 RemoteModel 类。

<?php
namespace App\Models;

use Laravel\Remote2Model\RemoteModel;

class ProductRemote extends RemoteModel {
    const CREATED_AT = null;
    const UPDATED_AT = null;

    protected $primaryKey = 'pid';
    protected $table = 'product';
    public $timestamps = false;

    public function getHandle()
    {
        /**
         * @var RemoteTool
         */
        $remoteTool = app('laravelremodel.tool');
        $condition = $remoteTool->queryToCondition($this->queryBuilder);

        $client = new \GuzzleHttp\Client();
        $res = $client->request('GET', 'http://127.0.0.1:18001/api/product', [
            'query' => [
                'condition' => $condition
            ],
        ]);
        $json = $res->getBody()->getContents();

        $list = json_decode($json, true);
        return $list;
    }

}

这里以查询 getHandle 为例子。默认提供 getHandle,updateHandle,insertGetIdHandle,deleteHandle 和 existsHandle 这 5 个方法。继承 RemoteModel 类后,不定义 getHandle 等这些方法,它会默认走 db 驱动,跟普通的 Model 类一样。

model 方法 类似 mysql 语法 用途
getHandle select 查询列表,查询详情,查询聚合运算(count,max 等)
updateHandle update 更新记录
insertGetIdHandle insert 插入记录
deleteHandle delete 删除记录
existsHandle select 判断是否存在

个人笔记#

这一次是入门篇,下一次估计会出源码篇。写了那么多年的代码,老是会发现服务化接口,就是查询一张表数据然后返回。搞得我经常怀疑人生。现在我坚定起来了,平时,我经常跟同事说 laravel 可以实现一秒服务化,他们都不相信。这次我可以证明给他们看。

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由 Summer 于 3年前 加精
windawake
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 18

大佬带带我

3年前 评论

厉害厉害,大佬这个是不是可以进一步封装的更简易通用一点呢

3年前 评论

sd 可以尝试兼容上述写法,显得更加标准化一些

具体看你怎么想 ,只是个建议 :thumbsup:

3年前 评论
windawake (楼主) 3年前
sparkinzy (作者) 1年前
windawake (楼主) 1年前
sparkinzy (作者) 1年前

对此我有一定疑问,既然业务拆分了,为什么还要用远程模型之类的操作,会脱离后台系统的控制,感觉仍然像是写一个垂直架构的系统一样

远程模型提供的方法也与 rest 接口功能高度重叠,不太明白应用场景是什么

照我的理解,项目后台提供通用的逻辑,由前端 (表示层) 拼装逻辑,可复用逻辑使用外观层,而不是在前端直接操作数据

3年前 评论
windawake (楼主) 3年前
游离不2

没看懂 :joy:

3年前 评论
windawake (楼主) 3年前

想法是好想法,我们已经干过这件事了 :joy:,然而随着业务的请求量上来后,响应速度会跟不上,我们现在走的是内网,响应速度勉强能接受,不过最终还是得考虑转成 RPC 的方式

3年前 评论
windawake (楼主) 3年前
还不出来 3年前
黑将军

很少看到有质量的博文了,为啥沉下去了呢

2年前 评论
windawake (楼主) 2年前