作者:戴泽军
前言
随着微服务架构成为业界主流,API 网关作为访问微服务集群内所有 API 的唯一出入口,地位显得尤为重要。
集群内微服务功能拆分越来越细,对后端而言,模块在独立性、复用性、可维护性方面的优势不言而喻。但对前端而言,复杂性却随之而来。一个前端页面,往往需要从数个甚至数十个 API 中请求数据,而这些 API,很可能还存在如下异构特性:托管 host 不同、实现语言不同、调用方式不同。
面对这样的难题,API 网关的需求应运而生:统一出口、隐藏实现、安全控制、流量控制、负载均衡、权限控制、API 管理等等。这些问题及其解决方案将在后续的文章中一一介绍。本期我们重点讨论 API 网关的另一个重要功能:API 编排。
API 编排的应用
所谓 API 编排,就是通过 API 网关实现一种机制,可以灵活调用和组装后端原生 API,使前端能够根据业务需求,定制化页面所需的聚合 API。其地位和作用,可相较于“Shell 之于 *nix”。
图注:图中方框大小示意调用时数据量大小
可以看出,与后端微服务 API 以“高内聚”为目标不同,聚合 API 以业务需求为导向,通过简单组合已有的原生 API,在后端代理调用多个 API,并对输出数据进行重新剪裁组装。
API 编排的优势
与前端直接调用多个异构的后端 API 相比,聚合 API 具有很明显的优势:
- 简化前端逻辑,一次 API 调用即可获取所有所需数据;
- 减少传输数据量,仅向前端发送需要展示的数据;
- 灵活的动态组合扩展特性,后端只需要实现“原子 API”,把业务需求交给消费方去自助配置,组合扩展;
- 同化调用方法,由 API 编排服务兼容异构实现的后端 API 的调用过程;
- 统一的身份认证和权限管理;
- 向前端隐藏第三方 API 的身份认证过程,由 API 编排服务兼容不同平台的 API 认证方法。
API 编排的痛点
面向没有编程基础的普通用户服务
由于 API 编排具有“用户自助”的特性,注定了其用户“既是生产者又是消费者”。而任何网络平台的用户,都必须假定为“没有编程基础”,即面向没有编程经验的普通用户服务。
功能需要覆盖完备的编程元素
API 编排需要构造多个 API 调用,捕获和剪裁输出数据,同时也可能存在分支和根据条件重复处理等需求。
我们的编程启蒙老师一定都讲过,编程无非就是顺序+选择+循环。可见,编程所需所有元素,在 API 编排中皆有需求。然而,在我们的用户是没有编程基础的普通用户的情况下,如何让他们理解和描述要进行的操作,是另一个难题。
没有现成的编程语言可用
站在程序员的角度,在各种高级编程语言百家争鸣的今天,描述和实现“ API 编排”需求的方法有千万种。
静态语言有 C、C++、C#、JAVA、GO 等供我们选择,动态脚本语言有 Python、Lua、Perl、JavaScript、Ruby、Lisp 等多种选择。可以说任意组合一门静态语言+一门动态语言,都可以完美胜任我们的“动态 API 编排”任务。然而,当我们的用户被定义为“没有编程基础”,该问题就开始变得扑朔迷离。
后端 API 实现上的异构特性
由于微服务拆分的原则是让每个服务足够独立,对服务的实现语言和使用的技术,并不会做严格的限制,所以微服务天生就有异构的特性。
如果是同一个 team 开发各个子服务,可能会在 API 提供方式、调用方法上做一些简单约定。如果是由不同的 team 开发这些子服务,甚至还会存在 HTTP/RPC、RESTful/非 REST 这些可选项。如果需要兼容第三方 API,则还会存在编程语言差异,使用的技术差异等。
因此,对于一个对兼容性有足够考虑的 API 编排系统而言,承认和处理后端 API 的异构问题,是必然绕不过去的弯。
原子化的描述 API 的调用方法及构造输入输出参数
虽然 API 编排不是直接由程序员编写代码来构造一个 HTTP/RPC 调用来完成 API 访问,但其最终要实现的效果与前者高度一致。由于后端 API 天生的异构特性,使我们必须提供一种准确且易懂的描述方式,让用户告诉我们如下问题的答案:
- API 的访问地址在哪?采用何种调用协议?
- 是否需要身份认证?采用什么方法构造这个身份认证参数?构造身份认证参数的 API 私钥是什么?
- 输入数参数从哪里来?放到哪里去?是否需要做简单的算术运算?
- 输出数据是否需要进行加工?多个 API 的输出如何重新组装输出?
因此,描述和实现构造 API 调用参数的过程和方法,成为设计 API 编排系统中最关键的一环。
编排第三方 API 的身份认证问题
由于一般对外提供 API 服务的系统,都会加入身份认证功能,来保证 API 不会被非法调用,以此保证服务器安全与稳定。对于需要兼容第三方 API 的 API 编排系统而言,需要采用一种通用的描述方法,让实现 API 的第三方可以准确的描述自己实现的 API 所使用的身份认证方法。
常见的身份认证方法有:OIDC、 JWT、 bearer Tokens、Basic Auth、Signature 等等。其中 Signature 认证方法只是使用“签名”认证方式的一种统称。实际上采用何种算法,使用什么步骤来构造这个“签名字符串”,都需要有统一的方法来详细描述。
说明:
常见的“签名”构造方法有:参数排序方法、追加字符串、计算 HASH 值、计算 HMAC HASH、AES/RSA 加密解密、hex/base64/url 编码解码等等。
由于第三方所使用的身份认证方法的多样性,且没有统一的标准,因此对 API 编排系统而言,如何原子化的定义和描述这些身份认证方法,也是一个不容忽视的大课题。
API 及 API 私钥的权限问题
API 私钥(如:登录网络平台的用户名密码)是用户访问第三方 API 平台的唯一身份证明数据,对用户数据安全有着至关重要的作用。因此,用户是不会轻易将此数据泄露给任何不可信的第三方的。API 编排需要代理用户向第三方 API 服务器发起 API 调用请求,所以必须由用户提供此私钥才能完成该操作。
那么,问题的核心即变为,我们需要设计一套严密的安全体系,让用户信任我们的系统,将 API 私钥托管在平台是安全可信的。安全托管这些 API 私钥的必要环节包括:加密上传,加密存储,任何第三方用户使用需要授权,后端透明使用,内容对任何用户不可见。
总结
本期简单介绍了 API 网关在微服务架构下的必要性。重点介绍了 API 网关的核心功能,API 编排的应用范围和设计上面临的诸多难题和挑战。由于 API 编排需要面对无编程基础的普通用户服务,使得设计 API 编排服务变得像实现“没有编程语言”的编程体验一样有趣。
后期文章,我们将继续探讨 API 网关和 API 编排设计和实现上的一些思考和探索。敬请期待。
关于全象云
全象云是青云科技自主研发的工具和平台,是基于云原生、解耦的、可插拔的开放生态系统,用于辅助构建企业各类数字化应用。
平台目前提供云上无代码和低代码两种应用开发模式,屏蔽了技术的复杂度。支持可视化设计器,让开发人员和业务用户能够通过简单的拖拽、参数配置等方式快速完成应用开发。同时集成了身份认证能力、容器 DevOps 能力,支持企业存量业务与全象云业务融合。平台还包含丰富的开发接口和强大的插件机制,开发者可根据需要不断拓展平台的应用能力。
全象云的愿景是:在企业生产经营的各个象限、各个环节提供软件构件或支持服务。