Skip to content
本页目录

简介

Fastball 是一套面向后端研发, 声明式界面开发框架. 核心定位是让常规后端人员可以无前端知识的前提下, 完成 Web 前端界面开发.

并允许专业前端介入, 可完成复杂界面交互以及组件扩展, 从而减少前后端环节的信息损耗以及研发成本.

原理概述

常见的 Web 软件, 从前后端交互的视角来看, 我们可以将其分为可视化的人机交互界面, 以及数据操作的接口服务组成.

我们认为在模式化的场景中, 数据操作的接口服务, 一定程度上可以描述人机交互界面, 因此可以考虑通过增强接口描述的方式, 来达到模式化界面的生成, 并加强前后端的联调协同性, 以此来提升 Web 软件的研发效率.

而且在 ToB 的企业软件行业, 模式化场景的占比会更高, 因此提出数据接口主导界面假设.

接口主导界面假设

而 Web 软件在生长的过程中, 如果业务有所变化, 抛开纯界面风格的变化外, 有以下几点假设:

  1. 界面上需要展现的数据交互, 需要后端接口支撑才能实现
  2. 存在一些接口逻辑变化, 而前端无需修改的情况, 最典型的比如变换业务查询条件, 这是无需界面感知的变化.
  3. 如果界面修改, 接口大概率也需要修改, 这是因为业务变化多数也会带来额外的信息获取或者提交诉求, 这些变化在不修改接口的情况下很难实现, 即 交互界面很难脱离接口服务独立完成.
  4. 校验规则多数情况下界面与接口一致, 少数情况下界面大于接口.
  5. 在前后端协同上来说, 前端属于使用者, 而后端是提供者, 例如接口的定义, 出入参的格式等. (GQL 这种暂不讨论, 其实本质上前端也仍然是使用者)

基于上述假设, 我们可以看到很多信息是后端服务接口定义, 而前端界面配合的方式在运作. 当然, 从业务的角度可能是产品原型驱动界面设计, 而界面设计驱动接口设计, 不过这是需求阶段, 在实现阶段仍然是后端接口供前端使用的模式.

另外, Web 系统中, 人机交互界面也存在一定模式化的现象, 这部分前端工作更多的是在处理字段以及接口的适配, 特别是 ToB 方向的企业软件中的中后台管理系统.

因此我们可以考虑将模式化的界面, 转化为标准的后端接口, 由后端接口产出模式化的界面, 也包括校验规则等交互要素. 同时提供 前端的二次开发以及调整的能力, 这样在非模式化, 或者在模式化边缘的一些场景, 也能够由前端自由发挥来得以满足.

场景分析: 数据列表

模式化场景中, 最常见的可能就是数据管理类节目, 即列表和表单组成的, 提供数据的增删改查能力, 这也是 LCDP 最常见的业务场景, 我们就以最典型的数据列表为例, 分析一下接口和界面的绑定程度.

示例界面如下图, 我们可以观察发现, 界面由 搜索区, 数据展示区, 全局操作区, 外加 记录操作区 组成. 搜索区 代表搜索条件, 而 数据展示区 用来展示数据, 查询时通过 分页查询数据 接口来获取.

table-mapping.png

如果我们认为 分页查询数据 接口在后台有一个代码相关的方法, 则该方法签名大概类似如下:

java
// 根据查询条件返回分页数据
Page<DTO> loadData(QueryDTO query);

我们不难发现, 列表的 查询区 要提交的数据, 其实就是入参 query, 如果界面上定义了 query 入参没有接收的参数, 则无法生效. 而且界面定义的字段类型, 也需要跟 query 中的属性一致, 否则也无法正常工作.

数据展示区其实也是相同的逻辑, 要展示的列, 必须要在返回的数据中有所体现, 并且展示的类型也需要跟返回数据的类型一致, 否则无法正常工作.

因此, 我们可以简单的理解数据接口和界面的绑定关系, 如下图所示.

table-api-mapping.png

与数据列表同理, 常见的 表单 所需要提交的字段, 必然和后台接口接收的 API 入参映射关系. 而其他 详情页 , 树组件 , 图表 等, 本质上都存在这样的映射关系.

因此, 我们可以考虑让数据接口, 以及其出入参承载更多的信息, 来表达界面的交互需求, 比如一些注解描述字段信息, 增加一些内置的容器类型, 比如 Range 表达查询区间等, 就已经可以满足交互界面的信息描述.

将上述例子的 全局操作区 以及 记录操作区 补全后, 我们写一个数据表格的代码如下:

java
@UIComponent
@ViewActions(@ViewAction(key = "new", name = "新增员工", 
    popup = @Popup(value = @RefComponent(EmployeeForm.class))))
public class EmployeeTable implements SearchTable<Employee, UserQuerier> {
    
    @Override
    public DataResult<Employee> loadData(UserQuerier querier) {
        return DataResult.build(repo.findByQuerier(querier));
    }

    @RecordAction(name = "删除")
    public void deleteEmployee(Employee employee) {
        repo.delete(employee);
    }
}

我们通过下图, 可以更直观的理解, 数据接口与界面之间的映射关系.

table-full-mapping.png

可视化的界面编辑

上述方式已经可以完成很多界面的开发, 但是真实业务开发过程, 难免需要对界面进行一些调整, 比如切换字段类型, 布局摆放等等. 这些细节很容易导致后端研发无法处理, 导致工作溢出, 最终还是要前端频繁介入.

因此 Fastball 提供了可视化的界面编辑, 提供了常见的界面调整能力, 可以让后端研发在不学习前端知识的前提下, 可视化且所见即所得的完成界面研发, 如下图:

plugin-editor.png