zoukankan      html  css  js  c++  java
  • D2js 的邦联式架构

    d2js 的接口单独看有点像小手工业者,每个人摆弄着自己的小功能,但是在 update 的一声号令下,它们也可以组合起来,发挥出整体的功效,变为流水线上的工人——这一切是自然而隐蔽的进行的,小手工业者不需要为进工厂而改变自己。

    这是怎么做到的呢?

    d2js 的接口可以通过浏览器地址栏调用。

    以下面的接口为例:

    d2js.exports.test = d2js.test = function(params){
        return {result : params.a + params.b}
    }

    在浏览器地址栏输入:

    http://localhost:8080/d2js/test.d2js?_m=test&params={%22a%22:1,%22b%22:2}

    image

    除了以json方式提供params,还可以分散在query string提供。

    http://localhost:8080/d2js/test.d2js?_m=test&a=1&b=2

    以该方式提供参数会视被为字符串:

    image

    需要在接口中做参数转换:

    d2js.exports.test = d2js.test = function(params){
       
        $V(this, params, {a: [T.int], b: [T.int]})
       
        return {result : params.a + params.b}
    }

    d2js 接口加以导出即可通过浏览器直接访问,使用浏览器地址栏就可以随意注入参数进行测试,这为后端开发提供了很大便利。

    作为普通函数,d2js 可以在其它函数中调用,如:

    d2js.test2 = function(params){
        var a = params.a, b = params.b
        return this.test({a: a * a, b: b * b})
    }

    可以在另一个d2js中调用:

    d2js.test2 = function(params){
        var a = params.a, b = params.b
        return this.callD2js('test.d2js', 'test', [{a: a * a, b: b * b}]);
    }

    可以使用表单调用:

    <form method="post" action="test.d2js?_m=test">
        a: <input type="number" name="a">
        b: <input type="number" name="b">
        <input type="submit">
    </form>

    也可以使用 ajax 调用:

    $.get('test.d2js', {_m : 'test', params: JSON.stringify({a:2, b:3})},

        function(s){
            console.log(s)
        }

    );

    用表单方式得到的是一个奇怪的 JSON 页面,不过这没有关系,通过一个简单的 wrapper 即可满足表单使用场景:

    d2js.exports.formEntry =
    d2js.formEntry = function(params){
        var result = this[params._entry](params);
        this.request.setAttribute('result', result)
        this.request.servletContext
            .getRequestDispatcher('/test.jssp')
            .forward(this.request, this.response);
        this.out.print('')    //阻止输出{success:true}
    }

    用法:

    <form method="post" action="test.d2js?_m=formEntry">
        <input type="hidden" name="_entry" value="test">
        a: <input type="number" name="a">
        b: <input type="number" name="b">
        <input type="submit">
    </form>

    test.jssp:

    <html>
    [%
        var result = request.getAttribute('result')
    %]
    <body>
        <h1>[%= result.result %]</h1>
    </body>
    <html>

    如需完全满足表单式应用场景, formEntry 函数还需要进一步完善,如实现跳转词典等等。

    d2js 接口支持 POST,PUT,GET,DELETE 语义,分别对应 modify, create, fetch, destroy 四个接口,也就是说,在上述配对情形中使用,可以不提供 _m 参数。

    一个典型的 d2js 文件具有 crud 四接口:

    d2js.fetch = function(){

        sql{.

              select .. from …

        .}

        return this.query(sql, params);

    }

    d2js.create = function(rcd){

         this.insertRow('table', rcd)

    }

    d2js.modify = function(rcd){

         this.updateRow('table', rcd)

    }
    d2js.destroy = function(rcd){

         this.deleteRow('table', rcd)
    }

    这四个接口都可以像上面一样独立使用。

    不仅如此,create, modify, destroy 三接口还可以被前端聚合!

    d2js 框架前端是一个主要为 DataTable 形态的数据结构。DataTable 可以改动多行,一起提交:

    table.rows[0]._set('name', 'Jack')
    table.rows[1]._set('name', 'Mike')
    table.rows[2].remove();
    table.addRow({name:'Mary'});
    table.submit();

    submit 函数调用时,上面代码中表的四行变动汇总为一个表变动信息,合并提交至 D2JS.prototype.update 函数,D2JS.prototype.update 函数根据行状态(edit,remove,new),调用相应的函数(modify, destroy, create)。该函数内为一个循环,处在一个事务中,一旦出错全体回滚。

    此外,前端还支持表间关联,提交父表时,可连带提交子表。

    提交多行的例子可参见 https://github.com/inshua/d2js 提供的示例。

    下面是例子中提交的JSON数据:


       "_m":"update",
       "table":{ 
          "name":"author",
          "src":"/d2js/d2js-test/author.d2js",
          "columns":[ 
             ...
          ],
          "rows":[ 
             { 
                "id":1,
                "name":"曹雪芹",
                "email":"caoxueqin@gmail.com",
                "tel":"111222333",
                "remarks":"曹雪芹先生是伟大的作家",
                "gender":"M",
                "info":{ 
                   "linkin":"123456aabb"
                },
                "_state":"edit",
                "_idx":0,
                "_origin":{ 
                   "id":1,
                   "name":"曹雪芹",
                   "email":"caoxueqin@gmail.com",
                   "tel":"111222333",
                   "remarks":"曹雪芹先生是伟大的作家",
                   "gender":"M",
                   "info":{ 
                      "linkin":"123456aa"
                   }
                },
                "_children":[ 
                   { 
                      "name":"book",
                      "src":"/d2js/d2js-test/book.d2js",
                      "columns":[ 
                         ...
                      ],
                      "rows":[ 
                         { 
                            "id":7,
                            "title":"红楼梦2",
                            "kind":"f",
                            "publish_date":"1977-02-03T00:00:00.000Z",
                            "isbn":"2323121",
                            "remarks":null,
                            "author":1,
                            "author_name":"曹雪芹",
                            "_state":"edit",
                            "_idx":0,
                            "_origin":{ 
                               "id":7,
                               "title":"红楼梦",
                               "kind":"f",
                               "publish_date":"1977-02-03T00:00:00.000Z",
                               "isbn":"2323121",
                               "remarks":null,
                               "author":1,
                               "author_name":"曹雪芹"
                            }
                         }
                      ]
                   }
                ]
             }
          ]
       }
    }

    根据数据提到的 src,和行状态,D2JS.prototype.update 函数会为为执行相应入库动作。

    可见,d2js 接口解耦程度极高,可聚可分,可联合作战,可独立作战,可用于 ajax 方式,表单方式、DataTable  方式,适合与各种前端模型混搭——当然,搭配 d2js 前端使用更珠联璧合。

    这套架构可以称为邦联式架构,每个接口都是独立的能行驶职能的政权,但也可以随时结合为一个更大的政权结构。

  • 相关阅读:
    Metaclass
    Pydantic
    Alembic
    SQLAlchemy
    django2:路由path语法
    Django 学习笔记之模型高级用法
    Flask拾遗总汇1
    Flask中before_request与after_request使用
    Flask 中字典数据返回(jsonify)
    浅析django的abstract,proxy, managed
  • 原文地址:https://www.cnblogs.com/inshua/p/6249160.html
Copyright © 2011-2022 走看看