1 Introdução
Com o crescimento do software como serviço e das arquiteturas de microsserviços, as APIs RESTful tornaram-se ubíquas nas aplicações modernas. Serviços como Slack, Stripe e AWS oferecem APIs extensas com centenas de métodos, criando desafios significativos para os desenvolvedores encontrarem a combinação correta de métodos para as suas tarefas.
O APIphany aborda este desafio através da síntese baseada em componentes especificamente concebida para APIs RESTful. O sistema utiliza tipos semânticos precisos para especificar a intenção do utilizador e direcionar o processo de pesquisa, permitindo a síntese automatizada de programas a partir de especificações de alto nível.
2 Contexto & Trabalhos Relacionados
2.1 Síntese Baseada em Componentes
A síntese de programas baseada em componentes tem sido aplicada com sucesso para navegar em APIs em linguagens como Java, Scala e Haskell. Estes sintetizadores recebem assinaturas de tipos e exemplos de entrada-saída para gerar fragmentos de programa que compõem chamadas de API com o comportamento desejado.
2.2 Desafios das APIs RESTful
Três desafios principais complicam a aplicação da síntese baseada em componentes às APIs RESTful: (1) a falta de tipos semânticos precisos nas especificações da API, (2) a necessidade de manipulação de dados semiestruturados e (3) preocupações de segurança com a execução de chamadas de API durante a síntese.
3 Arquitetura do APIphany
3.1 Inferência de Tipos Semânticos
O APIphany introduz um algoritmo de inferência de tipos que aumenta as especificações REST com tipos semânticos. Isto permite uma especificação mais precisa da intenção do utilizador e orienta o processo de síntese de forma mais eficaz.
3.2 Síntese de Manipulação de Dados
O sistema inclui técnicas de síntese eficientes para manipular dados semiestruturados comumente encontrados ao trabalhar com APIs RESTful, incluindo objetos e arrays JSON.
3.3 Execução Simulada
O APIphany emprega execução simulada para evitar a execução de chamadas de API reais durante a síntese, abordando preocupações de segurança e desempenho, mantendo a precisão da síntese.
4 Implementação Técnica
4.1 Formalismo do Sistema de Tipos
O sistema de tipos no APIphany estende os sistemas de tipos padrão com anotações semânticas. O julgamento de tipo central é formalizado como:
$\Gamma \vdash e : \tau \Rightarrow \phi$
Onde $\Gamma$ é o ambiente de tipos, $e$ é a expressão, $\tau$ é o tipo base e $\phi$ é o refinamento semântico que captura o comportamento da expressão.
4.2 Algoritmo de Síntese
O algoritmo de síntese utiliza pesquisa orientada por tipos com retrocesso. O espaço de pesquisa é definido por:
$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)$
O algoritmo poda candidatos inválidos precocemente usando restrições de tipo e refinamentos semânticos.
5 Avaliação Experimental
5.1 Metodologia
O APIphany foi avaliado em três APIs do mundo real (Slack, Stripe, GitHub) com 32 tarefas extraídas de repositórios GitHub e StackOverflow. As tarefas incluíram cenários de integração comuns, como recuperar e-mails de membros de canais Slack e processar dados de pagamento do Stripe.
5.2 Resultados & Desempenho
O APIphany encontrou com sucesso soluções corretas para 29 das 32 tarefas (taxa de sucesso de 90,6%). Entre estas, 23 soluções foram relatadas entre os dez melhores resultados de síntese, demonstrando a eficácia da abordagem orientada por tipos.
Taxa de Sucesso
90,6%
29/32 tarefas resolvidas
Top 10 Resultados
79,3%
23 soluções no top 10
Tempo Médio de Síntese
4,2s
Por tarefa
6 Exemplos de Código
Exemplo de tarefa de síntese para recuperar e-mails de membros de um canal Slack:
// Especificação de entrada
Tipo: ChannelName -> List[Email]
// Solução sintetizada
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 Aplicações Futuras & Direções
A abordagem do APIphany pode ser estendida para outros domínios, incluindo:
- Síntese de API GraphQL com introspecção de tipos
- Orquestração de microsserviços em aplicações cloud-native
- Integração de dispositivos Internet of Things (IoT)
- Integração de sistemas empresariais e modernização de APIs legadas
Trabalhos futuros incluem integrar aprendizagem automática para melhor inferência de tipos e expandir o suporte para padrões de API assíncronos.
8 Análise Original
O APIphany representa um avanço significativo na síntese de programas para APIs web, abordando desafios fundamentais que limitaram abordagens anteriores. A integração de tipos semânticos com a síntese baseada em componentes cria uma estrutura poderosa que preenche a lacuna entre métodos formais e tarefas práticas de integração de API.
O mecanismo de inferência de tipos no APIphany partilha semelhanças conceptuais com sistemas de tipos de refinamento em linguagens como Liquid Haskell [1], mas adapta estes conceitos para o mundo dinâmico e semiestruturado das APIs REST. Esta adaptação é crucial porque, ao contrário das linguagens estaticamente tipadas onde os tipos são explícitos, as APIs REST frequentemente dependem de esquemas JSON que fornecem informações de tipagem estrutural, mas não semântica.
A técnica de execução simulada é particularmente inovadora, inspirando-se na execução simbólica na verificação de programas [2], mas aplicando-a à síntese de API. Esta abordagem aborda a preocupação crítica de segurança de executar operações de API potencialmente destrutivas durante o processo de síntese. Técnicas semelhantes foram usadas na otimização de consultas de base de dados [3], mas o APIphany adapta-as para o domínio mais complexo da síntese de programas multi-API.
Quando comparado com outras abordagens de síntese como FlashFill [4] para transformações de strings ou SyPet [5] para síntese baseada em componentes, o APIphany demonstra como o conhecimento específico do domínio (semântica de API REST) pode melhorar dramaticamente a eficácia da síntese. A taxa de sucesso de 90,6% em tarefas do mundo real excede significativamente o que seria esperado de sintetizadores de propósito geral, apoiando a hipótese de que a síntese consciente do domínio é essencial para aplicações práticas.
O componente de manipulação de dados aborda um desafio fundamental na integração de API: o desajuste de impedância entre os formatos de dados da API e as necessidades da aplicação. Este problema é reminiscente dos desafios de transformação de dados em processos ETL (Extract, Transform, Load) [6], mas o APIphany resolve-o através da síntese em vez de especificação manual. A abordagem poderia potencialmente influenciar práticas futuras de design de API, encorajando informações de tipo mais sistemáticas nas especificações da API.
Perspetivando o futuro, as técnicas do APIphany poderiam ser integradas com grandes modelos de linguagem para geração de código de API. Embora modelos como o GPT-3 [7] mostrem capacidades impressionantes para geração de código, faltam-lhes a precisão semântica e garantias de segurança da síntese orientada por tipos. Uma abordagem híbrida combinando geração neural com verificação orientada por tipos poderia representar a próxima fronteira na síntese prática de programas.
9 Referências
- 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.