1 引言
随着软件即服务和微服务架构的兴起,RESTful API在现代应用中已无处不在。Slack、Stripe和AWS等服务提供了包含数百种方法的广泛API,这给开发人员寻找适合其任务的方法组合带来了巨大挑战。
APIphany通过专门为RESTful API设计的基于组件的合成技术应对这一挑战。该系统使用精确的语义类型来指定用户意图并指导搜索过程,实现了从高层规范自动生成程序。
2 背景与相关工作
2.1 基于组件的合成
基于组件的程序合成已成功应用于Java、Scala和Haskell等语言的API导航。这些合成器接收类型签名和输入输出示例,生成能够组合API调用以实现预期行为的程序片段。
2.2 RESTful API挑战
三个主要挑战使得将基于组件的合成应用于RESTful API变得复杂:(1) API规范中缺乏精确的语义类型,(2) 需要处理半结构化数据整理,(3) 合成过程中执行API调用的安全性问题。
3 APIphany架构
3.1 语义类型推断
APIphany引入了一种类型推断算法,通过语义类型增强REST规范。这使得能够更精确地指定用户意图,并更有效地指导合成过程。
3.2 数据整理合成
该系统包含高效的合成技术,用于处理在使用RESTful API时常见的半结构化数据,包括JSON对象和数组。
3.3 模拟执行
APIphany采用模拟执行来避免在合成过程中执行实际的API调用,解决了安全性和性能问题,同时保持合成准确性。
4 技术实现
4.1 类型系统形式化
APIphany中的类型系统通过语义注解扩展了标准类型系统。核心类型判断形式化为:
$\Gamma \vdash e : \tau \Rightarrow \phi$
其中$\Gamma$是类型环境,$e$是表达式,$\tau$是基础类型,$\phi$是捕获表达式行为的语义精化。
4.2 合成算法
合成算法使用带回溯的类型导向搜索。搜索空间定义为:
$P := \text{apiCall}(p_1, \dots, p_n) \mid \text{map}(P, \lambda x. P) \mid \text{filter}(P, \lambda x. P) \mid \text{compose}(P, P)$
该算法使用类型约束和语义精化早期剪除无效候选。
5 实验评估
5.1 方法论
APIphany在三个真实API(Slack、Stripe、GitHub)上进行了评估,使用了从GitHub仓库和StackOverflow提取的32个任务。任务包括常见的集成场景,如从Slack频道检索成员电子邮件和处理Stripe支付数据。
5.2 结果与性能
APIphany成功为32个任务中的29个找到了正确解决方案(成功率90.6%)。其中,23个解决方案位列合成结果前十名,证明了类型导向方法的有效性。
成功率
90.6%
29/32 任务已解决
前十结果
79.3%
23个解决方案进入前十
平均合成时间
4.2秒
每任务
6 代码示例
检索Slack频道成员电子邮件的合成任务示例:
// 输入规范
类型:频道名称 -> 邮件列表
// 合成解决方案
function getChannelEmails(channelName) {
const channels = conversations_list();
const targetChannel = channels.find(c => c.name === channelName);
const memberIds = conversations_members(targetChannel.id);
return memberIds.map(id => {
const user = users_info(id);
return user.profile.email;
});
}
7 未来应用与方向
APIphany的方法可以扩展到其他领域,包括:
- 具有类型自省的GraphQL API合成
- 云原生应用中的微服务编排
- 物联网设备集成
- 企业系统集成和遗留API现代化
未来工作包括集成机器学习以改进类型推断,并扩展对异步API模式的支持。
8 原创分析
APIphany代表了Web API程序合成的重大进步,解决了限制先前方法的基本挑战。语义类型与基于组件的合成的结合创建了一个强大的框架,弥合了形式化方法与实际API集成任务之间的差距。
APIphany中的类型推断机制与Liquid Haskell [1]等语言中的精化类型系统在概念上有相似之处,但将这些概念适应于REST API的动态、半结构化世界。这种适应至关重要,因为与类型显式的静态类型语言不同,REST API通常依赖JSON模式,这些模式提供结构信息但不提供语义类型信息。
模拟执行技术尤其具有创新性,借鉴了程序验证中的符号执行[2]思想,但将其应用于API合成。这种方法解决了在合成过程中执行潜在破坏性API操作的关键安全问题。类似技术已用于数据库查询优化[3],但APIphany将其适应于更复杂的多API程序合成领域。
与FlashFill [4]用于字符串转换或SyPet [5]用于基于组件合成的其他合成方法相比,APIphany展示了领域特定知识(REST API语义)如何显著提高合成效果。在真实任务上90.6%的成功率显著超过了通用合成器的预期表现,支持了领域感知合成对于实际应用至关重要的假设。
数据整理组件解决了API集成中的一个基本挑战:API数据格式与应用程序需求之间的阻抗失配。这个问题让人联想到ETL(提取、转换、加载)过程中的数据转换挑战[6],但APIphany通过合成而非手动规范来解决它。这种方法可能影响未来的API设计实践,鼓励在API规范中提供更系统的类型信息。
展望未来,APIphany的技术可以与大型语言模型集成用于API代码生成。虽然像GPT-3 [7]这样的模型在代码生成方面显示出令人印象深刻的能力,但它们缺乏类型导向合成的语义精度和安全性保证。结合神经生成与类型导向验证的混合方法可能代表实用程序合成的下一个前沿。
9 参考文献
- Vazou, N., et al. "Refinement types for Haskell." ICFP 2014.
- Baldoni, R., et al. "A survey of symbolic execution techniques." ACM Computing Surveys 2018.
- Neumann, T. "Efficiently compiling efficient query plans for modern hardware." VLDB 2011.
- Gulwani, S. "Automating string processing in spreadsheets using input-output examples." POPL 2011.
- Feng, Y., et al. "Component-based synthesis for complex APIs." OOPSLA 2017.
- Vassiliadis, P. "A survey of extract-transform-load technology." IJDWM 2009.
- Brown, T., et al. "Language models are few-shot learners." NeurIPS 2020.
- Polikarpova, N., et al. "Program synthesis from polymorphic refinement types." PLDI 2016.