QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

企业数据移动化

  • 2014-06-03
  • 本文字数:4598 字

    阅读完需:约 15 分钟

企业正努力通过 RESTful 接口实现企业数据的移动化,但开发移动应用和 REST API 是非常耗时的工作。

我们研究了两种技术,可以显著缩短上市时间。可执行的 Schema(建立于模型驱动开发和约定优于配置)从现有 Schema 创建 RESTful API 和多表 UI,只需要几分钟时间。声明式的行为为逻辑和安全带来类似电子表格的强大功能和简单性,它基于完全可编程的 JavaScript 模型。

我们将简要地回顾现有的关键技术,借助它们的先进性,吸取市场中的教训。然后我们将提供可执行的 Schema 和声明式行为的具体细节。

当前的方法

承诺加快交付速度是很有吸引力的,在过去十年间确实诞生了一些很棒的产品。首先,让我们简要分析当前的方法,从而得出一些经验教训。

模型驱动开发

模型驱动架构 [1] 和模型驱动工程 [2] 这样的方法,已经在构建部分系统元素方面有一些成功案例。虽然有承诺,但其真正的机会在于:

  • 直接构建可执行的系统,而不是需要理解和集成的组件(如 Beans、Transfer Object);
  • 借助云 / 移动技术;
  • 消除 Model/Schema 的冗余和同步的复杂性。

约定优于配置:Ruby, Grails……

生成可执行系统的概念已经被 Ruby、Grails,Roo 等流行的产品占据,它们使用约定优于配置 [3],根据模型生成 UI 界面和代码。这是一个简单的 Grails 例子:

(点击查看大图)

(点击查看大图)

能够快速构建 Web 应用是一件好事,但如果要想获得显著的、更大的价值,就要实现:

  • 应用能够更加完整。例如提供可编辑的(内嵌 Lineitem 修改)主 / 从表(显示订单的 Lineitem)Grid,自动关联显示产品名称而不是数字;
  • 提供多表业务逻辑支持(修改逻辑和安全业务逻辑非常冗长乏味);
  • 应用部署于云技术平台,REST 和 HTML 5/JavaScript;
  • 避免生成代码的缺陷,例如当原始输入(数据模型)变化时,重复生成或丢失自定义逻辑。

移动后端

移动后端即服务(Mobile Backend as a Service,MBaaS)是一个新的分类,关注于云技术,例如 REST/JSON。DreamFactory 和 SlashDB 这样的产品为你的 SQL 数据创建了完整的 RESTful API,并提供了便利的表格浏览用户界面。

但这肯定仅仅是个开始,如果你能实现以下功能,就不难想像其价值了:

  • 扩展表浏览功能,实现完整的多表应用,提供主 / 从、导航等功能;
  • 提供业务逻辑,确保数据修改时触发正确的计算和校验;
  • 使用别名(Alias)/Projection 提供自定义多表资源。

建议的方法

通过引入以下理念可以显著加强这些方法:

  • 可执行的 Schema,将 Schema 作为模型,你可以建立 REST/ 云服务,预先为多表 UI 和 API 提供通用行为模式,这是个立即可执行的系统;
  • 声明式、面向业务的行为能够提供声明式的 API 扩展、逻辑和安全行为支持。其真正的价值是在一个很高的抽象层面交付这些行为,这更像是面向业务的需求,而不是代码;
  • 在标准语言中集成命令式语言支持。使用像 JavaScript 这样的标准语言,为模型提供程序事件支持。

所以,开发团队能够在接近业务的抽象层运行和交付,显著提高了速度。他们能将 BDD 故事翻译成可运行的软件,以确认理解和发掘下一组行为。这样就明显地减少了误解,因为相关干系人已经看到了正在运行的软件,读懂了“代码”。

可执行的 Schema

要想有立竿见影的效果来满足业务需求,我们要运行现成的应用。也就是说,只要将我们的系统连接到 Schema,就会有完全可执行的 API 和应用软件,正如下面所描述的。

默认的应用程序

建立一个具有丰富功能、支持移动的后台应用是有可能的。前提是虽然“前台”应用需要 UI 草图,但数据维护这一大类应用遵循一套常见的模式,它们可以通过 Schema 来创建。

下图演示了一些数据维护应用完整功能的常见模式:

  • 搜索 / 过滤、分页列表/表单视图、可排序的列标题;
  • 外键驱动的多表应用软件行为:
  • * 主 / 从表(客户的多个订单);
  • * 下钻导航(第 2 张图,订单的项目,通过右下侧的放大镜或 Zoom 按钮);
  • * 自动表关联(Join):显示产品名称,而不是数字编号;
  • 数据编辑支持,包括可编辑的表格,查找(查找部分)和错误处理。

表关联功能非常有趣,它相当常见。在下面的例子中,Product 外键是 Product Number,而不是 Name,这是很常见的模式。理想情况下,系统了解这种情况(数字外键,例如 Product Number)并自动关联更适合的字段(Name)。我们不仅有可执行的 Schema,而且是马上就能用的。

(点击查看大图)

(点击查看大图)

默认的REST API

RESTful API 是云 / 移动应用的架构选择。该 API 不仅能提供移动应用接入,还可为其它系统提供 Web Service 访问。

数据库到 REST 的映射也非常直接,只需要:

  • 为每个数据库表、视图和存储过程建立 REST Endpoint;
  • 提供 Get/Put/Post/Delete 支持(即常说的 CRUD 操作),并支持:
  • * 过滤和排序;
  • * 常见的模式,包括分页、分析数据库结构和相关的数据,以及乐观锁。

其结果是一个“扁平”的关系型 API。这是个好的开始,但我们需要继续去扩展它。

声明式的行为

我们建议模型不要复制 Schema,由于下面这些关键行为,因此有必要扩展它。

富 REST API:多表资源、别名和 Projection

我们的“扁平”API 是个好的开始,但仍然需要富“面向文档”的 API。该需求是为移动开发人员提供方便的 API 模型的同时,最小化多个查询的延时。

这样的对象有点像支持别名和 Projection 的关系型视图。但是,与视图不同,它们不是扁平的。它们支持嵌入的“子资源”对象,例如 Order 对象有 LineItem 和 Shipment 信息。

这样的“多表视图”可以通过点击,或者这样的语法进行定义:

复制代码
Create Resource OrdersResource
from Orders (id as orderNumber, customer.name as customerName),
SubResource Items as LineItems via <fkName>
(name as product.name, qty as qtyOrdered...)
SubResource Shipment as Shipents via <FkName>
(...)

逻辑:与电子表格相似的响应(Reactive)

业务逻辑是绝大多数系统的关键因素。它们通常是繁琐的代码、包含大量的变更检查和扩散逻辑,以及大量的 SQL(包括缓存提升性能)等等。

通常认为,这样的逻辑是特定领域的(正确),并且必须以命令式和过程式语言进行开发(错误)。声明式的方法将能够显著提前和加速软件交付和维护。并且已经存在这样的解决方案。

目前越来越重视 UI 事件处理中的响应,例如模型到视图的同步。但最常用的是电子表格,当相关值发生变化时,单元格公式的响应,会进行重新计算,当然还能将它们串起来。虽然对非程序员来说很简单,但电子表格提供了足够的能力,解决了不同寻常的复杂性。

响应非常适合于数据库事务逻辑:

  1. 给数据库表的列,或者“虚拟列”(是模型的一部分,用于事务处理,但并不物理保存)设置表达式;
  2. RESTful Put/Post/Delete 操作修改了关联的值时,将触发调整相应的值;
  3. 同时进行校验(余额 < 信用)。

最有趣的事务是多表,按照我们的表达式,可以引用关联数据(customer.balance := sum(orders.amount_total where paid = false)。这让系统不仅能够检测变化,还要提供持久化(读取 / 写入相关数据、缓存和优化等等)。

需要注意的是对列的逻辑封装将导致继承复用。上面的例子中,我们声明的系统观察和响应 orders.amount_total 或 paid 标志的变化。

声明式的逻辑肯定是无序的。因此系统必须推导出执行顺序,例如通过依赖图。这对维护很有意义。自动排序意味着你增加 / 改变逻辑时,不需要担心执行顺序的具体细节。

由于省去了依赖管理、扩散和 SQL 处理,实现了意义非凡的简洁性和可读性。意义非凡指的是扩展了 order 的幅度,因此下面的逻辑,是虚拟的需求规范,是可以直接执行的:

复制代码
lineitem.amount = row.product_price * row.qty_ordered
lineitem.product_price = copy(row.product.price)
orders.amount_total = sum(lineitem.amount)
customer.balance = sum(orders.amount_total where paid = false)
validate customer as row.balance <= row.credit_limit

但是,没有银弹。并不是所有逻辑都能够声明,关键的条款需要正确地集成处理逻辑。这些在下面描述。

安全性

大多数系统的另一个关键需求是安全性。除了熟悉的端点接入,系统必须实现行和列的实例级别的安全性。例如,您可能希望某些人只能看到自己所在地区的订单。

很多系统在视图级别提供这样的功能,但这导致定义和维护大量的视图。一个更好的办法是将基于角色的安全性封装到表中,并确保它能够在跨多表资源时可以重用。

复制代码
Role SalesRep authorized for Orders
Columns(orderDate, …)
Rows (region = $user.region)

其中 $user 表示一种建议的机制,将用户与命名的值(例如 region)关联,可以用于过滤表达式的参数。

程序扩展

可执行的 Schema 和声明式行为能够提供价值,但仅当它们与常见的程序扩展进行集成后才潜力无限。

服务端 JavaScript

通过 Schema 可以直接为每个表创建 JavaScript 行对象类型,以及列和相关数据的存取方法。这很像 Ruby Active Record,它们是持久化感知(Persistence-aware)和逻辑感知(Logic-aware)的。它们确保了在处理修改时,执行正确的响应逻辑。

此外,你能在服务端 JavaScript 中处理它们发布的事件。事件包括常见的模型(插入前、修改前)并对 JavaScript 提供完全的访问(发送消息、启动程序等)。JavaScript 是一种优秀的语言,它几乎运行于所有系统,而且大多数开发者都相当熟悉。

UI 创建

客户端的扩展性也很重要。默认的 UI 可能很强大和有效,但主要适合于后台应用程序。对于前台办公应用,有很多要求,因此应能够开发任何 UI 界面。

有两种可行的方法。第一,默认的 UI 可以正向工程(代码生成)到你偏爱的平台 /IDE 中,你将它作为起点。

或者,可以将内在的模型移出,将默认 UI 制作成组件,以参数化的 iFrame 方式嵌入到更大的应用程序中。这保持了模型间的关联,避免代码生成的“你拥有它”的影响。

自定义 API

最后,创建声明式 API 丝毫没有消除构建自定义 API 的能力和需求。

总结

我们在这列出了现实的方法:

  • 从现有 Schema 快速创建移动应用和默认的 RESTful API;
  • 扩展 API,定义多表层级资源;
  • 使用声明式“响应”表达式增加行为,管理修改逻辑和行访问,提供电子表格的简单性和强大功能;
  • 与服务端 JavaScript 集成,提供复杂的行为。

作者注: Espresso Logic 已经在实现这个愿景,提供了一些前面所描述的元素。如果你想试试,我们提供了免费的评估版本和零安装系统,你可以使用自己的数据库。我们始终期待与你交换意见,以提高我们的技术。

参考文献

[1] The OMG effort

[2] Model Driven Engineering (see this , this and this )

[3] Convention Over Configuration

关于作者

Val Huber拥有超过 20 年的快速开发和维护业务应用的构建技术经验。在 Espresso 之前,Val 是 Versata 公司的 CTO,该公司是 2000 年前 5 大 IPO 之一,最初由一批远见者如 Paul Allen 和 SAP 的 Hasso Plattner 投资成立。在 Versata,他领导 J2EE 环境下的大规模事务和流程应用开发。Versata 支持数以万计的并发用户,部署于许多财富 500 强公司,包括 ADP、Equifax、Fidelity、IBM 和 Sears 等. 在 Versata 之前,Val 是 Sybase 公司(现在是 SAP 的一部分)的架构师。他也是 Wang 的高度评价的 PACE(Professional Application Development Environment,专业应用开发环境)背后的驱动力。PACE 提供了关系型数据库,以及完全自动化的工具套件用于报表和交互式应用。Val 拥有多项专利,并享有由他的团队开发的商业相当成功的系统。

查看原文链接: Restify and Mobilize Your Data

2014-06-03 01:112063

评论

发布
暂无评论
发现更多内容

Websocket集群解决方案

Jeremy Lai

websocket 集群 发布订阅模式

银行APP用户体验外滩峰会即将开启!四大亮点抢先看

易观分析

金融 银行 易观

WiFi、蓝牙、NFC 哪家强?短距离无线通信技术对比分析

元器件秋姐

无线通信 元器件选型 元器件电商平台 元器件采购

远程控制软件如何像素级还原设计稿色彩?

RayLink远程工具

远程控制软件 远程办公软件 远控软件 远程桌面连接 RayLink

深度分析React源码中的合成事件

goClient1992

React

商家和企业如何选择KOC合作:要明确推广目标、选对平台和博主

石头IT视角

2022 VDC应用与服务专场:帮助开发者实现增长共赢

Geek_2d6073

手写一个react,看透react运行机制

goClient1992

React

能不能手写Vue响应式?前端面试进阶

bb_xiaxia1998

Vue

算法题学习---合并k个已排序的链表

桑榆

算法题 11月月更

常用硬件接口知识

芯动大师

RS232、RS485 11月月更 硬件接口 VGA

漫游Hadoop(一):NameNode公平队列

冰心的小屋

hadoop hdfs

前端开发面试题自测

loveX001

JavaScript

【愚公系列】2022年11月 微信小程序-app.json配置属性之window

愚公搬代码

11月月更

2022-11-09:给定怪兽的血量为hp 第i回合如果用刀砍,怪兽在这回合会直接掉血,没有后续效果 第i回合如果用毒,怪兽在这回合不会掉血, 但是之后每回合都会掉血,并且所有中毒的后续效果会叠加 给

福大大架构师每日一题

算法 rust 福大大

没有什么比过时或不准确的文章更快的削弱你对产品的信心。

鸿蒙之旅

OpenHarmony

react高频面试题总结(附答案)

beifeng1996

React

老生常谈React的diff算法原理-面试版

beifeng1996

React

问:React的setState为什么是异步的?

beifeng1996

React

对于MUI的实现原理以及遮罩蒙版和numbox以及侧滑导航的事件监听的运用和实战

恒山其若陋兮

Vue 前端 11月月更

OceanBase获奖!蚂蚁集团第三次入选世界互联网领先科技成果

OceanBase 数据库

详解typora配置华为云图床

乌龟哥哥

11月月更

假如面试官问你Babel的原理该怎么回答

loveX001

JavaScript

20道前端高频面试题(附答案)

loveX001

JavaScript

2022 VDC安全隐私专场:提升用户产品安全体验,携手伙伴共建安全新生态

Geek_2d6073

远程办公软件RayLink公有云版正式上线,专业连接限时免费至12月底!

RayLink远程工具

远程控制软件 远程办公软件 远控软件 远程桌面连接 RayLink

Windows下载安装Vue开发者工具(VueDevtools)

不觉心动

Vue 11月日更 11月月更

深入React源码揭开渲染更新流程的面纱

goClient1992

React

MUI实战之switch和事件以及transparentBar与slide的实战与深入运用

恒山其若陋兮

前端 11月月更 黎燃

时延测评|免费又好用的低延时远程控制软件竟是它!

RayLink远程工具

远程控制软件 远程办公软件 远控软件 远程桌面连接 RayLink

一天梳理完react面试高频知识点

beifeng1996

React

企业数据移动化_REST_Val Huber_InfoQ精选文章