Tratar APIs como "first-class citizens" pode ser um desafio e tanto, principalmente quando estamos em um contexto de entrega rápida ou de prova de conceito. Como desenvolvedor, admito que priorizo resolver a lógica de negócio escrevendo código, do que discutindo contratos ou requisitos não funcionais.
O modelo de trabalho ilustrado acima pode ser conhecido por "bottom up", "code first", ou apenas por "aquela forma que a gente geralmente utiliza em nossos projetos". Onde focamos primeiro no código, e deixamos para depois questões relacionadas à integração dos componentes.
Kirsten Hunter ilustra bem os efeitos colaterais de tal prática:
APIs are created as an afterthought once the product has already been created as a tightly coupled system, with the frontend website and backend system entwined together in a highly codependent way and the REST API having to be ‘shoe-horned’ into this system as a separate entity.
Não há nada fundamentalmente errado com essa dinâmica (inclusive, há opiniões a favor desse conceito), mas com o mundo cada vez mais "microservices-driven", pensar primeiramente na interface e em quem irá usá-la pode antecipar problemas, diminuir riscos e definir contratos mais sólidos.
Não é raro escutarmos em pleno 2020 histórias sobre times distintos trabalhando em uma grande solução, que quando colocaram seus serviços para funcionar juntos, descobriram uma série de problemas de integração (ou até mesmo que eles simplesmente não resolviam o problema).
API-First pode ser grosseiramente resumido em "trate APIs como first-class citizens".
Em outras palavras, a proposta é que APIs sejam consideradas partes fundamentais do ecossistema de um produto, devem ser parte de sua estratégia e construção, e não apenas um "extra" ou um "side product".
O DZone define API-First da seguinte forma:
(...) is a strategy in which the first order of business is to develop an API that puts your target developer’s interests first and then build the product on top of it (be it a website, mobile application, or a SaaS software). By building on top of APIs with developers in mind, you and your developers are saving a lot of work while laying down the foundations for others to build on.
Elas devem ser tão cruciais quanto usuários são em estratégias user-centric e a experiência mobile é em um approach mobile-first. Utilizar uma abordagem api-centric fará com que o design funcione de uma ótica diferente (possibilitando maior cuidado em relação a consistência e reuso), e que o negócio gire em torno do contrato que está sendo definido (ocasionando maior interação com outros stakeholders de forma antecipada, dentro do tempo de vida de desenvolvimento).
E se pararmos para analisar friamente o que essa ideia significa, ser api-centric é no fim das contas ser user-centric (ou customer-centric).
O usuário nesse caso passa a ser outro desenvolvedor (do mesmo time, da mesma empresa, ou de terceiros), portanto, Developer eXperience também é parte fundamental dessa estratégia, e vem embutida em sua prática, como ilustra o "Understanding the API-First Approach to Building Products":
Consumers of APIs are most often developers, and developer experience (DX) can make or break the success of an API. API first ensures that developers have positive experiences using your APIs. Well-designed, well-documented, consistent APIs provide positive developer experiences because it’s easier to reuse code and onboard developers, and it reduces the learning curve.
Lars Trieloff, no Adobe Tech Blog, escreve sobre três princípios fundamentais para o sucesso da prática, que acredito serem essenciais para compreender a real motivação por trás da ideia.
Vale estressar esse ponto: Pessoas utilizando a sua API são os seus usuários, e a sua API precisa ser projetada com esses usuários em mente.
Partindo do princípio que a API é o caminho mais importante de interação com o seu produto, isso significa que ela deve ter um investimento de tempo equivalente (ou superior) ao tempo investido no desenvolvimento de (por exemplo) interfaces gráficas.
Your implementation will change frequently, your API should not.
Sua API se torna um contrato que servirá como especificação para a implementação, portanto, o ideal é pensarmos como duas coisas separadas. Conforme a sua aplicação for evoluindo é muito provável que a sua implementação mude, mas o contrato deve (dentro do possível) manter-se o mesmo.
Sua API precisa ser compreendida por pessoas que não estavam envolvidas em seu desenvolvimento. E aqui é difícil escaparmos da necessidade de documentação.
E por documentação, é impossível deixar de questionar todo o esforço envolvido em ter uma documentação válida, atualizada, e que deveras é usável. Ferramentas estão disponíveis, e existem diferentes formas de automatizar esse processo. Tais ferramentas servem não somente para a criação de documentação, mas também da especificação em si (que pode ser também consumida por uma máquina). Por exemplo, RAML e Swagger, já abordados no blog, são excelentes iniciativas para resolver essa questão.
Mas além disso, seguir padrões é outro esforço que trará resultados na usabilidade da API:
When it comes to documentation for APIs, structured documentation beats unstructured documentation. Following a standard pattern for URLs, resource types, request methods, headers, request parameters, and response formats will make it easier to explore and understand functionality, and reduces surprises when your API grows.
Hypermedia parece outra excelente ideia, uma vez que serve como documentação e oferece meios para humanos e máquinas compreenderem melhor a sua funcionalidade.
API-First é sobre fazer a API antes da interface web e mobile? Ou seria sobre primeiro fazer o design da API e a partir daí passar para a implementação?
Uma ótica interessante sobre esse debate pode ser lida no "What Is An API First Strategy? Adding Some Dimensions To This New Question", do apievangelist.com.
Durante a pesquisa para a escrita desse post, fui exposto a diferentes perspectivas, e é muito provável que eu tenha apresentado elas de forma "misturada" até aqui:
Qual visão você pretende adotar depende muito do contexto. Haverá casos em que o produto já existe, soluções já estão no ar, e você fará o movimento para um consumo baseado em APIs. Ou, com sorte, você fundará uma startup e terá controle o suficiente para primeiramente produzir uma API e depois as interfaces gráficas.
Assim como há diferentes "níveis de REST" que podemos usar no cotidiano, API-First pode ser adotado em diferentes níveis e maneiras.
No meu caso, que atualmente trabalho em um ambiente enterprise e tenho pouca influência sobre o negócio, é basicamente sobre discutir o contrato primeiro, e ter uma especificação que sirva como documentação e que guie o meu desenvolvimento.
Na primeira vez que ouvi falar sobre esse conceito, me perguntei como que de forma prática é possível exercitá-lo. De lá para cá já me deparei com diferentes formas e processos para adoção.
Inclusive, durante meu período na Loadsmart, cheguei a falar exatamente sobre isso em um lightning talk na Python Sul, e sobre como estávamos montando esse processo.
O contexto pode variar de acordo com o público alvo de sua API. Por exemplo, no artigo "Understanding the API-First Approach to Building Products" do swagger.io, há uma boa descrição do que não pode faltar quando o assunto é prover APIs dentro de uma organização:
Muitos desses passos, mesmo em um contexto onde você esteja provendo APIs para usuários externos, fazem completo sentido (e provavelmente já façam parte da fase de arquitetura e design do seu produto). Possuir um portal no qual você exponha as suas APIs, como elas funcionam e como um possível parceiro é capaz de integrar-se a ela, não são apenas artefatos de engenharia, também são possíveis artefatos de negócios.
Se você já pratica design by contract, muito do que foi dito aqui já faz parte do seu cotidiano.
E com o microservices fazendo cada vez mais "parte da normalidade", API-First pode parece mais um buzzword para descrever
o que já é comum. Ainda assim, não é raro escutarmos histórias sobre dois serviços diferentes que não são
capazes de se comunicar, ou de prestadores de serviço que produzem interfaces gráficas para empresas e que na hora de
vinculá-las ao back end a coisa simplesmente não funciona.
Lembro que o meu primeiro contato com API-First foi fruto de uma necessidade de expor certa funcionalidade para um certo grupo de possíveis parceiros. Pensar na API primeiro foi um exercício interessante, uma vez que envolveu pensar numa plataforma coesa, e permitiu levar em consideração questões como reuso (que ocasionou na própria empresa utilizando a API produzida).
Lembro também que o feedback foi muito bom, uma vez que certos mercados possuem uma postura bem conservadora, e pensar primeiro no usuário mostrou preocupação genuína com o problema do usuário e consequentemente com o produto sendo escrito.
Contratos são difíceis de serem alterados depois de implementados, então discutí-los antes permite uma resposta mais rápida (e indolor) à mudanças, além de proporcionar uma possível "paralelidade" entre servidor e consumidor no desenvolvimento da funcionalidade (reduzindo assim tempo de release e aumentando a interação durante a implementação do contrato por ambas as partes).
Por maior que esse post seja, no fim das contas API-First é algo fundamentalmente simples, que assim como o agile, parte do princípio que as pessoas (e seus problemas) são o que realmente importa.
Até a próxima.