美团开放平台将美团各类业务提供的扩展服务封装成一系列应用程序编程接口(API)对外开放,供第三方开发者使用。开发者可通过调用开放平台提供的OpenAPI获取数据和能力,以实现自身系统与美团系统协同工作的业务逻辑。以外卖业务场景为例,开发者可以在自己为外卖商户开发的应用中通过调用美团开放平台提供的API,提供外卖订单查询、接单、订单管理等一系列功能。如下图所示:
开放平台为开发者提供的OpenAPI以HTTP接口的形式提供。以平台提供的订单查询接口为例,对应的HTTP请求如下所示:
从使用SDK的开发者角度来看,基于SDK封装的基础功能来编写调用开放平台接口的代码,大致逻辑如下所示:
MeituanClientclient=DefaultMeituanClient.builder(developerId,signKey).build();//设置请求参数MeituanRequestrequest=newMeituanRequest("/api/order/queryById");request.setParam("orderId","10046789912119");MeituanResponseresponse=client.invokeApi(req);if(response.isSuccess()){longprice=(long)response.getField("price");Stringphone=response.getField("customerPhone");intorderStatus=(int)response.getField("status");//完成业务逻辑}else{log.warn("queryorderfailedwithresponse={}",response);//处理接口调用失败的逻辑}从上述代码可以看出,提供基础功能的SDK已经能够为使用者提供较大的便利。相比从零开始编码对接OpenAPI,使用SDK可以帮助开发者省去处理通信协议、公共参数放置、安全签名计算和返回状态码解析的工作量。但开发者在编写代码设置API的业务参数字段的环节,仍需对照API文档逐个手工填充字段名并按字段类型赋值,并且在获取API返回的业务字段时也需自主填充字段名并解析数据类型,存在较大的不便且易出错。
为解决此问题,我们需要在SDK的能力上更进一步提供对参数富模型的支持,即为每个API提供模型化封装的请求参数和返回参数结构,让使用SDK的开发者可以更加专注于业务逻辑的开发。
在SDK加入参数富模型的支持后,从使用者的角度来看,需要编写的代码如下所示:
MeituanClientclient=DefaultMeituanClient.builder(developerId,signKey).build();//设置请求参数QueryOrderRequestrequest=newQueryOrderRequest();request.setOrderId("10046789912119");//调用接口MeituanResponse
从上述公式可以看出,当SDK所需支持的API数量和编程语言数量达到一定数量时,通过纯人工编码去开发和维护SDK的成本会非常高。需要通过技术手段自动生成和测试SDK中的绝大部分代码,以达到在成本可控的前提下,为开发者提供支持多种编程语言版本的富模型SDK的目标。
要为开发者提供一个支持参数富模型功能的OpenAPISDK,我们需要实现以下主要功能:
其中,通信协议封装和接口基础契约封装是一次性工作,并且其逻辑是相对稳定的。对于SDK所需支持的每一种编程语言,只需投入有限的成本开发一次对应代码逻辑,即可支撑SDK的整个生命周期。而要为平台开放的1000余个API提供支持多种编程语言的参数富模型功能,靠人工编写和维护代码是极其低效的,我们考虑通过代码自动生成技术,对SDK中的参数富模型代码进行自动化生成。
更进一步,在实现了参数富模型代码自动生成后,我们可以通过持续集成(ContiniousIntegration)和持续发布(ContinuousDelivery)技术,将SDK的生成、测试和发布流程也尽可能地做到自动化。整体的SDK自动生成流程设计如下图所示:
实现了以上流程后,即可做到在开放平台的任意API的参数模型发生变化时,由系统自动生成和发布最新版本的SDK供开发者使用。我们将在下文详述如何通过代码自动生成、持续集成和持续发布等技术手段实现上述流程。
我们最终的目标是为开放平台的每个OpenAPI,自动生成供SDK使用的请求参数模型代码(Request类)、返回参数模型代码(Response类)和调用示例代码(Example),并且代码自动生成机制要支持SDK适配的多种编程语言。以Java和C#编程语言为例,我们要生成的目标代码如下图所示:
要达成上述目标,首先需要考虑的是代码自动生成技术的选型,目前业界主流的代码生成技术分为以下几类:
考虑到开放平台SDK中,需要自动生成的OpenAPI参数富模型代码和调用示例代码均具备相对较强的规则性和模式性,我们选择基于代码语料自动生成代码的技术路线。
基于代码语料自动生成代码需要“语料”+“规则”两个核心元素,我们可以通过解析API元数据并结合领域专用语言(DSL)作为语料模板,生成代码语料,再基于语料特性为不同的编程语言定制代码生成规则,最终将“语料”+“规则”输入代码生成器以完成目标代码的生成。整体流程如下图所示:
以生成JavaSDK中的参数富模型代码为例,需要用到的代码语料包含两部分。第一部分为类的基本信息,由元数据解析器在解析API的元数据时生成,其包含的内容和具体生成方式如下表所示:
第二部分为语料模板,我们以DSL(DomainSpecificLanguage)作为中间语言加以描述,如下所示:
Request和Response类中其余的getter方法、setter方法、类注解等元素的生成原理和步骤均和以上相同,此处不再赘述。在DSL语料模板中所有的元素处理完成后,我们即可得到供Java编程语言使用的请求参数类和返回参数类的完整代码。
对于其他的编程语言(例如Python),我们使用的API元数据和元数据解析逻辑和Java是一致的,不同点在于DSL语料模板和语言转换引擎。当需要对SDK新增一种编程语言的支持时,我们只需要对目标语言建立DSL语料模板并提供相应的转换逻辑,即可支持该语言的请求参数类和返回参数类的代码自动生成。
通过同样的技术手段,我们还可以自动生成每个OpenAPI的调用示例代码,并将示例代码展示接口文档中供开发者参考。
调用示例代码的生成的逻辑相对参数模型代码更加简单。我们使用API元数据中的类名和字段信息(元数据中也包含了每个字段的examle值,可用于在代码示例中生成字段赋值的逻辑)填入代码语料中,再执行语言转换引擎生成目标代码即可。以Java编程语言为例,用于生成API调用示例代码的DSL语料模板如下所示:
<#settingnumber_format="computer">MeituanClientmeituanClient=DefaultMeituanClient.builder(10000L,"xxxxx").build();<#assignreqVarName=classNameuncap_first/>${className}${reqVarName}=new${className}();<#ifprivateFields&&(privateFieldssize>0)><#listprivateFieldsasfield>${reqVarName}.set${field.fieldNamecap_first}(${field.exampleValue!""});#list>#if><#ifjavaApiMeta.needAuth>StringappAuthToken="xxxx";MeituanResponse<${javaApiMeta.responseClass}>response=meituanClient.invokeApi(request,appAuthToken);<#else>MeituanResponse<${javaApiMeta.responseClass}>response=meituanClient.invokeApi(request);#if>if(response.isSuccess()){<#ifjavaApiMeta.responseClass=="Void">System.out.println("调用成功");<#else>${javaApiMeta.responseClass}resp=response.getData();System.out.println(resp);#if>}else{System.out.println("调用失败");}在使用API元数据和代码语料模板执行基于DSL的语言转换引擎后,生成的API调用示例代码如下所示:
MeituanClientclient=DefaultMeituanClient.builder(developerId,signKey).build();//设置请求参数OrderQueryByIdRequestrequest=newOrderQueryByIdRequest();request.setOrderId(1000224201796844308L);//调用接口MeituanResponse
搞定参数富模型代码和调用示例代码的自动生成后,下一步是通过持续集成和持续发布技术,确保开发者在任何时刻均能获取到最新版本的SDK。传统由人工编译、测试和上传发布SDK的模式,开发者得到SDK版本更新的周期短则数周,长则数月。我们的目标是将这个周期缩短到分钟级别:当SDK的基础逻辑和API参数模型有任何变更发生时,通过持续集成和持续发布的能力,在数分钟内将包含此变更的新版本SDK发布给开发者使用。
我们基于美团自研的流水线引擎来驱动SDK的持续集成和持续发布。流水线的执行可以看作是对生成SDK的“原材料”一步步加工,最终交付到线上的过程。先通过下图了解整体流程:
首先我们监听可能导致SDK需要发布的变更,包括通过Binlog机制监听API元数据的变更,以及通过GitHook机制监听SDK基础逻辑代码仓库Master分支的变更。一旦监听到有变更产生,通过触发器去触发SDK持续集成和发布流水线的运作。
流水线开始运作后,首先执行SDK构建组件,SDK构建组件会并发执行两个操作:
以上两个操作完成后,执行代码合并和代码编译,将结果提交到流水线执行下一个步骤。接下来由自动化测试组件完成对SDK的单元测试和端到端自动化测试,通过后提交到流水线执行下一个步骤。最后由自动发布组件完成SDK的打包、上传、下载链接生成和版本信息生成等一系列操作,并最终将最新版本SDK发布到官网供开发者下载。
通过上述能力的建设,我们打通了SDK自动生成的整个环节,以自动化的方式完成代码生成、构建、测试、集成、发布等一系列行为,最终实现了在低人力投入的前提下持续向开发者交付最新版本SDK的目标。
通过最近半年数据的对比,我们可以看出开发者使用SDK后在接口对接环节遇到的疑难问题明显减少。基本达到了我们最初提高开发者接入效率,降低平台研发和运营处理工单成本的目标。
后续,我们将会计划继续完善SDK的代码自动生成逻辑,并为SDK添加更多编程语言的支持,为接入美团开放平台的开发者提供更好的体验。
国家新一代人工智能开放创新平台被称为“人工智能国家队”,是聚焦人工智能重点细分领域,充分发挥行业领军企业的引领示范作用,有效整合技术资源、产业链资源和金融资源,持续输出人工智能核心研发能力和服务能力的重要创新载体。此前,已有百度、阿里、腾讯等15家公司先后获批建设。本次美团成功申报,标志着美团的科研创新能力获得了国家层面认可,达到“国家队水平”。
飞宏、照东、宇豪、王鸿等,均来自美团到店事业群/餐饮SaaS事业部。