3 pontos por GN⁺ 2024-04-27 | 1 comentários | Compartilhar no WhatsApp
  • As decisões de nomenclatura e modelagem de recursos de API são a parte mais difícil e importante do design de APIs. Os recursos formam o modelo mental dos usuários sobre como o produto funciona e quais são suas funcionalidades.
  • A equipe da Increase usa o princípio de "sem abstrações" para orientar o design de APIs.

Abordagem da Stripe para design de API

  • Uma parte significativa da equipe da Increase trabalhou anteriormente na Stripe e leva em conta os valores de design de API que fizeram sucesso na Stripe.
  • A Stripe é excelente em extrair a funcionalidade central de domínios complexos em abstrações que os usuários conseguem entender e usar com facilidade. (Ex.: PaymentIntent, que abstrai as diferenças entre Visa e Mastercard)
  • A maioria dos usuários da Stripe são startups em estágio inicial desenvolvendo produtos sem relação com pagamentos, então não precisam conhecer os detalhes de cartões de crédito. Eles querem integrar a Stripe rapidamente e se concentrar no desenvolvimento do produto.

Usuários da Increase e princípios de design de API

  • Já os usuários da Increase têm conhecimento profundo sobre redes de pagamento, e o motivo de escolherem a Increase é justamente a conexão direta com a rede e a profundidade da integração.
  • Eles querem saber exatamente quando a janela do FedACH se fecha e em que momento uma transferência ocorre, e entendem que configurar códigos SEC diferentes em transferências ACH pode afetar o timing de retorno.
  • Tentar esconder a complexidade fundamental dessas redes não simplifica a vida deles; só causa frustração.
  • A partir de conversas com os primeiros usuários, a equipe chegou ao princípio de "sem abstrações" e o aplicou ao design da API.

Como o princípio de "sem abstrações" influenciou o design da API

  • Uso da terminologia real: em vez de criar nomes próprios para recursos e propriedades da API, a equipe usa o vocabulário da rede subjacente. (Ex.: os parâmetros de transferências ACH usam os nomes de campos da especificação Nacha)
  • Imutabilidade: ao usar eventos reais como modelo, mais recursos da API se tornam imutáveis. Funciona bem agrupar clusters de recursos imutáveis em objetos de ciclo de vida de máquina de estados. (Ex.: o campo status do objeto ach_transfer e alguns subobjetos imutáveis gerados conforme o ciclo de vida da transferência avança)
  • Separação de recursos por caso de uso: quando o conjunto de ações que o usuário pode executar varia muito dependendo da instância do recurso, ele é dividido em vários recursos. (Ex.: transferências ACH de saída e de entrada são separadas em recursos distintos)

Aderência da equipe de engenharia à abordagem

  • A equipe de engenharia se comprometeu a seguir essa abordagem.
  • Ao projetar uma API complexa por anos, é preciso tomar continuamente pequenas decisões incrementais; assumir previamente o compromisso com princípios básicos reduz a carga cognitiva dessas decisões.
  • Por exemplo, no caso do campo Input Message Accountability Data, necessário ao enviar dinheiro ao Federal Reserve, em uma API com muitas abstrações seria preciso pensar em como dar a esse campo um nome mais "amigável"; na Increase, o engenheiro simplesmente o nomeia como input_message_accountability_data e segue em frente.

Opinião do GN⁺

  • O nível de abstração de uma API pode variar conforme o nível de experiência do desenvolvedor no domínio do produto e a energia que ele pretende investir na integração. Por isso, ao projetar uma API, é importante considerar o nível de abstração adequado para os desenvolvedores que vão integrá-la.
  • Se você estiver construindo uma API com alto nível de abstração, é preciso pensar com cuidado antes de adicionar novas funcionalidades. Por outro lado, se estiver construindo uma API com baixo nível de abstração, é importante manter essa linha e resistir à tentação de adicionar abstrações.
  • Usar diretamente a terminologia da rede ou do protocolo subjacente pode ajudar os desenvolvedores a entender o underlying system, mas também pode se tornar uma barreira de entrada para quem está tendo o primeiro contato. Por isso, parece importante investir bem em comentários e documentação.
  • Utilizar objetos immutable no design de APIs pode ser eficaz para manter a consistência dos dados e evitar side effects. Por outro lado, pode ser inconveniente quando atualizações de dados são necessárias, então é preciso considerar bem esse trade-off.
  • Separar recursos por caso de uso pode aumentar a complexidade da API, mas no longo prazo pode elevar a previsibilidade. Ainda assim, se houver granularidade excessiva, a usabilidade pode cair, então é importante encontrar um nível adequado.

1 comentários

 
GN⁺ 2024-04-27
Opiniões no Hacker News
  • É bom oferecer tanto APIs com abstrações de baixo nível quanto APIs com abstrações de alto nível

    • APIs de baixo nível permitem controle detalhado, mas exigem conhecimento especializado
    • APIs de alto nível oferecem operações simplificadas voltadas a casos de uso comuns
    • Manter uma separação clara entre as duas APIs reduz a pressão para adicionar abstrações ou casos especiais a cada uma delas
    • É bom fornecer materiais para que os clientes aprendam como migrar de uma API para a outra
  • Gostei da parte que explica por que a Increase escolheu uma abordagem diferente

    • Ao projetar algo fundamental, o contexto importa muito, mas as pessoas normalmente não percebem isso o suficiente
  • A verdadeira capacidade da Stripe está em conhecer seus clientes e oferecer a simplicidade que eles querem

    • A Increase também entende bem do que seus clientes precisam e demonstra um foco semelhante ao criar diretrizes de projeto para construir um ótimo produto
  • Isso se parece com o padrão de projeto "Ubiquitous Language" da Domain-Driven Design, em que a implementação usa os mesmos termos reais usados pelos especialistas do domínio

  • É preciso usar uma linguagem que os especialistas do domínio consigam entender

    • Se o usuário conhece arquivos NACHA, usar outra terminologia o obriga a manter um mapeamento mental
    • No caso da Stripe, como o usuário não é um especialista do domínio, vale a pena criar abstrações que sejam compreensíveis e ao mesmo tempo escondam detalhes desnecessários
  • Sem uma abstração como POSIX, os aplicativos teriam que escrever adaptadores para todos os sistemas de arquivos suportados

  • Dizem que parte da estrutura da API é construída em uma relação 1:1 com base em especificações controladas externamente

    • O que acontece quando essas especificações evoluem ou mudam? Isso vira uma nova API?
  • Uma coisa difícil de modelar de forma limpa em APIs de pagamento é que os sistemas de pagamento representam de maneiras diferentes os papéis de pagador e recebedor em devoluções de pagamento

    • Por exemplo, em certos sistemas, pagador e recebedor podem permanecer nas mesmas posições do pagamento inicial
    • Já em outros sistemas, eles se invertem