前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >根据接口自动生成表单探索

根据接口自动生成表单探索

作者头像
用户2936994
发布2022-07-21 13:54:26
7200
发布2022-07-21 13:54:26
举报
文章被收录于专栏:祝威廉祝威廉

问题

API接口其实是不易用的,所以我们有了PostMan之类的工具去辅助我们调用,同时,它也是不清晰的,所以我们需要有文档或者API Mock之类的工具。但是我们将文档和接口分开本身就是一件不幸的事情,他们一旦分开,很难保持同步,这也是问题的源泉。再次,开发者不去回顾代码逻辑,他自己都无法清楚自己的程序到底需要什么参数,每个参数应该会被用户怎么使用。

从另外一个角度来看,接口属于典型的“写”少“读”多的。也就是你变动你的代码是少数,而用户使用它是多数。所以如何让一个接口自解释,易于使用是非常重要的。首先要对人友好,人学会了,才能将其应用于其他程序里。

一切输入都可以抽象为表单,一个漂亮易用,尽量避免输入的表单就是对人友好的。而一个接口的输出,都可以理解为是表格。一个好的易用的返回结果,应该是二维平铺的,现实世界有大量的程序(也包括人)对它更易于接受。复杂的嵌套徒增理解障碍和引起别人的错误以外,似乎没有什么额外的用处。

代码语言:javascript
复制
表单 -> 你的系统 -> 表格

解决方案

要能让接口自动生成一个易于使用的表单,从而简化人们对接口的使用和了解,必须修改接口的开发规则。我们认为,一个接口应该由两部分组成。

  1. 参数描述,接口描述
  2. 具体的业务逻辑

Scala 将class 和 object进行了分离。我认为也非常适合API。我们将一个API的参数等描述信息放到Object里,然后业务逻辑放到class里。 比如,我有一个创建脚本文件的接口,对应的描述信息如下:

代码语言:javascript
复制
object CreateScriptFileAction {

  object Params {
    val USER_ID = Input("userId", "")

    val PARENT_ID = Dynamic(
      name = "parentId",
      subTpe = "TreeSelect",
      depends = List(Params.USER_ID.name),
      valueProviderName = CreateScriptFileAction_Params_PARENT_ID.action)

    val IS_DIR = Select("isDir", List(), valueProvider = Option(() => {
      List(
        KV(Option("Directory"), Option(ScriptFile.DIR.toString)),
        KV(Option("File"), Option(ScriptFile.FILE.toString))
      )
    }))

    val CONTENT = Input("content", "")

    val LABEL = Input("label", "")


  }

  def action = "createScriptFile"

  def plugin = PluginItem(CreateScriptFileAction.action,
    classOf[CreateScriptFileAction].getName, PluginType.action, None)
}

这里,通过Params我们描述了这个接口需要的所有参数。其中Dynamic参数表示,该参数需要用户先填写USER_ID才会自动触发生成。是属于一个联动的表单组件。

根据前面的描述,前端会自动生成如下表单:

用户填写完userId后,自动多了一个栏目:

接着在Class里完成业务逻辑,比如这里的逻辑比较简单,就是获取userId然后再输出。

代码语言:javascript
复制
class CreateScriptFileAction extends ActionWithHelp {
  override def _run(params: Map[String, String]): String = {
    JSONTool.toJsonStr(List(Map("userId" -> params(CreateScriptFileAction.Params.USER_ID.name))))
  }

  override def _help(): String = JSONTool.toJsonStr(FormParams.toForm(CreateScriptFileAction.Params).toList.reverse)
}

_run 是业务逻辑。 _help 则是方便你控制表单的生成。

前面我们看到,通过简单地描述,我们可以生成很好的表单。但是表单里核心难点是,表单的元素存在依赖。比如A选择框依赖于B输入框。用户在B输入了,A才能拿到数据。极端点,用户输入了一个用户id,表单其他所有的选项会自动得到填充。

这个,我们通过Dynamic 类型可以得到很好的解决。解决办法很简答,Dynamic描述了该字段依赖于哪个字段,并且依赖的字段一旦发生变更,应该到哪去获取数据。

如何构建向导

我们知道,单个接口并不能完成一个用户的诉求。通常,要完成一个诉求,通常需要多个接口共同工作,通常这些接口是需要顺序关系的。通过向导,我们可以将完成特定诉求的接口们组织起来。现在,我们看如何完成这么一件事情。

任何使用web-platform 开发的项目,只要安装一个特定的插件,就自动具备表单功能。首先我们看首页:

这是当前应用的所有的接口列表。我们点击第一个Go to nav page,它是一个特殊的功能。

我们输入用户,选择我们需要的向导:

输入用户1,然后自动会提示所有已经创建好的向导,这里我们选择【创建导航】,这里会有一个向导帮助我们做事情。

这里我们,创建一个新的导航,需要三个步骤。我们只要按步骤走,就可以创建一个新的向导。但是我们也看到问题,如果导航项有非常多该怎么办?我们可以单独通过接口[createAPINavItem]为一个已经存在的向导不断添加新的步骤:

大部分参数都会有自动提示。这意味着,我们可以利用已有的接口去创建新的向导,从而能够帮助用户做更复杂的事情。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档