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 于 2年前 加精
windawake
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 18

大佬带带我

2年前 评论

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

2年前 评论

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

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

2年前 评论
windawake (楼主) 2年前
sparkinzy (作者) 11个月前
windawake (楼主) 10个月前
sparkinzy (作者) 10个月前

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

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

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

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

没看懂 :joy:

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

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

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

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

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

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