Com certeza você já deve ter ouvido (ou lido) a frase “The world runs on software”. Bom, se o mundo roda através de softwares, podemos dizer que “os softwares rodam através APIs”, haja vista que um dos principais aspectos de aplicações modernas é a conectividade com outras aplicações terceiras (o que obviamente, é feito através do consumo de APIs), especialmente com a ampla adoção das plataformas de nuvem públicas.
Existem, entretanto, diferentes metodologias e padrões disponíveis no mercado para que seja possível a uma aplicação, se conectar a outra. Recentemente (leia-se, nos últimos 5 ou 6 anos), entretanto, o padrão adotado pelo mercado para comunicação entre aplicações é aquele conhecido por REST (Representational State Transfer). Em linhas gerais, um serviço RESTful é aquele que tem a capacidade de, dentre outros aspectos, comunicar-se com outras aplicações através da internet utilizando apenas o protocolo HTTP (e portanto utilizando seus verbos), com informações podendo ser agrupadas em diversos formatos, dentre eles, JSON, o mais comum.
Documentação é sempre importante em qualquer contexto, certo? E é claro que, com APIs REST, não é diferente. No sentido de prover um mecanismo robusto e padronizado para se documentar APIs REST, surgiu a especificação Open API (que no momento em que este texto foi escrito, estava em sua versão 3.0). Através dessa especificação, ferramentas como Swagger surgiram para simplificar o processo de documentação destas APIs. Por hora, é o que você precisa ter de informação para seguir.
Não pretendo esgotar o assunto REST nesse texto. A ideia aqui é trazer o contexto geral da discussão antes de entrarmos no assunto tema propriamente dito. Se você está sendo apresentado a este conceito apenas agora, recomendo fortemente que você efetue a leitura do conteúdo disponível neste link para ter uma visão um pouco mais ampla do assunto. É fundamental compreender bem (pelo menos os conceitos básicos) o assunto para entender o restante deste artigo.
O cenário
Neste momento quero lhe convidar a pensar um pouco sobre o processo mais comumente executado pelos profissionais de desenvolvimento para se criar/disponibilizar APIs com suas operações dentro de uma aplicação. Com excessão de algumas peculiaridades que possam existir no processo, na maioria dos casos as seguintes etapas são executadas:
- Cria-se um novo projeto de API (se for .NET, por exemplo, cria-se um Web API);
- Implementa-se toda a regra de negócios sobre seus respectivos padrões (Repository pattern, Dapper, etc.);
- Adiciona-se a configuração do Swagger (ou alguma tecnologia equivalente) para documentar as operações disponibilizadas pela API;
- Cria-se algum tipo de aplicação cliente e/ou wrapper para que seja possível consumir o(s) serviço(s) criado(s);
Neste texto quero focar no passo 4, isto é, o processo de se criar algo para consumir uma API REST já documentada. Considere a Figura 1, a seguir.
Figura 1. Fragmento da UI do Swagger para o microserviço Arda.Kanban
Pergunta: se você fosse construir um client (uma aplicação MVC, um SPA ou mesmo uma aplicação mobile) para consumir esse serviço do Arda (este especificamente adiciona uma uma nova entrada de apontamento para um workload existente). O que você faria? Imaginando que você esteja trabalhando com uma aplicação MVC, provavelmente seria:
- Criar uma classe de modelo que representaria o objeto Appointment;
- Adicionaria a assinatura do método de inserção em sua interface;
- Implementaria este método no repositório específico;
- Injetaria a dependência no controller;
É claro que esta é apenas uma suposição. Esse processo poderia ser modificado consideravelmente dependendo dos patterns implementados em sua aplicação. Mas isso não é o importante. O mais importante mesmo é que este seria um processo bem trabalhoso, especialmente se a API que se está consumindo for bem grande, com centenas e milhares de operações.
Agora pense em um modelo ainda mais avançado de consumo. Imagine que você, arquiteto responsável pela estrutura desta API REST, foi informado que, no sentido proporcionar uma experiência rica de consumo para os clientes de seu produto, precisará criar e disponibilizar um SDK (ou wrapper) para facilitar a conexão de outras aplicações à sua API. Ainda melhor, imagine que a designação é que esta API seja disponibilizada pelo menos nas seguintes linguagens: C#, Java e Python. Seria bem complexo e demorado gerar isso de forma manual, certo?
Além disso, existe o aspecto de evolução das APIs. Imagine o quão trabalhoso seria atualizar um SDK implementado de maneira manual?
Auto Rest
Auto Rest é um projeto open source (disponível aqui) do time do Azure que, com base no arquivo de manifesto entregue pela especificação Open API mencionada anteriormente (portanto, o arquivo gerado pelo Swagger é válido), é capaz de gerar wrappers de consumo da respectiva API. O melhor? Em diferentes linguagens. Hoje são suportadas: C#, Go, Java, Node.js, TypeScript, Python, Ruby e PHP.
Se o seu olho brilhou assim como o meu quando conheci o projeto, existe mais uma boa notícia. O projeto é multi-plataforma e pode ser executado em Windows, Linux e MacOS. Outra aspecto bacana é que ele é inteiro escrito em Javascript (com TypeScript), o que mostra como de fato a Microsoft está se preocupando em criar soluções escaláveis com tecnologias open source.
Seguem dois links úteis:
- O processo de instalação do Auto Rest para seu sistema operacional pode ser encontrado aqui: https://github.com/Azure/autorest#installing-autorest;
- O processo de manutenção e operação com Auto Rest: https://github.com/Azure/autorest/blob/master/docs/managing-autorest.md;
Para exemplificar seu funcionamento, irei demonstrar como estamos criando um SDK em C# para o Arda utilizando Auto Rest. Nossa primeira providência neste sentido foi integrar cada microserviço do Arda com o Swagger (como você pode ver na Figura 1). O processo de integração do ASP.NET Core (tecnologia do Arda) com Swagger está super detalhado neste documento da Microsoft.
Após isso, o que fizemos foi ajustar o Swagger gerado automaticamente pela aplicação para melhorar as saídas do SDK. Após esse ajuste, nosso Swagger base para o microserviço “Arda.Kanban” ficou similar aquele apresentado pela Listagem 1.
Listagem 1. Arquivo base de geração para o Swagger no microserviço Arda.Kanban
Após isso, geramos então nosso SDK para o “Arda.Kanban” utilizando o Auto Rest. Para fazer isso, executamos a seguinte linha de comandos (exibida pela Listagem 2).
autorest -Input kanban.json -CodeGenerator CSharp -OutputDirectory Kanban -Namespace ArdaSDK.Kanban -ClientName KanbanClient
Listagem 2. Gerando o SDK com base no Auto Rest
Basicamente o que estamos fazendo é:
- Utilizar o comando “autorest” para invocar a criação do SDK com base no arquivo do Swagger;
- Utilizar a propriedade “-Input” para informar o path do arquivo do Swagger;
- Utilizar a propriedade “-CodeGenerator” para informar qual será a linguagem sobre a qual o código deverá ser gerado;
- Utilizar a propriedade “-OutputDirectory” para informar o destino dos arquivos gerados;
- Utilizar a propriedade “-Namespace” para informar o nome do namespace para os arquivos C# que serão gerados;
- Utilizar a propriedade “-ClientName” para informar um nome para o cliente;
O resultado do processamento desta linha de comandos pode ser visualizado através da Figura 2.
Figura 2. Arquivos gerados pelo Auto Rest
Em linhas gerais o que o Auto Rest faz é: 1) “Olhar” para a referência (arquivo do Swagger) e gerar os modelos. 2) Gerar as interfaces para criar o “manifesto” dos métodos e operações. 3) Implementa os métodos de fato nas classes sólidas. 4) Disponibiliza o acesso aos métodos implementados através de extension methods (note o nome “Extensions” ao final do arquivo).
Pronto. Sua SDK foi gerada. Algumas considerações importantes:
- Idealmente, deveria existir alguém no projeto de software que cuidasse especificamente da geração do arquivo Swagger. Como tudo é baseado nele, quanto mais detalhado e bem modelado ele for, melhor será a geração do código por parte do Auto Rest;
- Não sendo possível ter esse profissional, a integração com o Swagger através do método que mencionamos no início desse texto pode ser uma boa opção, entretanto, é fundamental que se ajuste o Swagger gerado antes de passá-lo para a geração do código por conta do Auto Rest. Isso porque ao fazer de maneira automática, poderão existir problemas de ilegibilidade de métodos e propriedades;
- É super importante fornecer o máximo de informações possível quanto a resposta de determinado método. Comportamentos inesperados podem ocorrer se este aspecto não for atendido;
É isso. Espero que você tenha gostado e possa aprofundar um pouco mais seus estudos sobre Auto Rest. Ele poderá poupar bastante tempo de desenvolvimento se projetado e executado da maneira correta em seu projeto de software.
Forte abraço e até o próximo.
Facebook
Twitter
Instagram
LinkedIn
RSS