O API-First

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.

Code-First

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.

Capitão América levantando o martelo do Thor
Não faça o dev ser merecedor para utilizar a sua API (comicbookmovie.com)

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).

O que é API-First?

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).

API-centric == Developer Experience

E se pararmos para analisar friamente o que essa ideia significa, ser api-centric é no fim das contas ser user-centric (ou customer-centric).

Thor preocupado com o martelo
Não duvide da vontade do seu usuário. Ele vai descobrir um jeito de levantar o martelo (ibtimes.com)

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.

Os 3 princípios

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.

1. Your API is the first user interface of your application

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.

2. Your API comes first, then the implementation

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.

3. Your API is described (and maybe even self-descriptive)

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.

Thor aliviado com o martelo
Se o Thor tivesse uma documentação bacanuda para como funciona o martelo, Caps teria usado antes (cinemablend.com)

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.

Camadas: API-First Development x API-First Design

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:

  • Do ponto de vista de negócio, é sobre ter uma API primeiro e torná-la um produto per se;
  • Do ponto de vista de tecnologia, é sobre ter uma plataforma primeiro;
  • Do ponto de vista de arquitetura, é sobre ter um design coeso, reusável, e construído através da colaboração de diferentes stakeholders;
  • Do ponto de vista de UX, é sobre ter uma API bem estruturada e documentada;
  • Do ponto de vista do desenvolvedor, é sobre ter uma especificação antes de partir para a implementação.

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.

Os passos

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.

Capitão América com o martelo do Thor
Ver outro dev usando sua API é tão sensacional quanto o Caps usando o martelo (youtube.com)

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:

  • Brainstorm: Primeiro identifique os serviços chave do negócio e suas capabilities. Descubra quais tipos de APIs deveriam ser oferecidas, descreva os casos de uso para tais APIs, e aponte potenciais endpoints baseados nesses casos de uso.
  • Identifique os stakeholders: Quem são os potenciais usuários dentro da sua organização? Tente construir uma visão clara e compartilhada com os demais times da sua empresa. Permita que stakeholders influenciem no design da API e envolva-os em melhorias e mudanças.
  • Projete um contrato: O contrato estabelecerá uma série de padrões e boas práticas. Descreva todas as APIs e garanta que elas funcionarão de acordo com o acordado.
  • Crie um style guide: Com um style guide será possível ter consistência entre diferentes times e serviços, dentro de uma mesma organização. Status codes, versionamento, erros, padrões de rota, etc. Possuir uma especificação comum reduzirá o atrito para adoção de sua API por outros desenvolvedores da organização.
  • Implemente governança: Isso ajudará a estabelecer padrões e reforçar outcomes esperados. Essa prática pode envolver de code reviews a contract tests.
  • Automatize processos: Utilize ferramentas para automatizar o processo de geração da documentação de API, validação de estilo, mocking, versionamento, etc. Prover todo o ferramental necessário para que o usuário possa interagir com sua API facilmente faz parte desse passo.
  • Controle o seu portfolio de APIs: Não é raro esquecermos que certo serviço já existe, portanto, possuir um sistema que auxilie no gerenciamento e tracking de APIs é fundamental.
  • Crie um portal para desenvolvedores internos: Tenha um lugar centralizado onde usuários possam encontrar a documentação, especificação e demais contratos. Developer Experience é importante.

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.

Considerações finais

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.

Referências