Por que uma API precisa de uma versão
Uma página HTML interna pode mudar de forma de um dia para o outro. Todo visitante recebe a marcação nova na próxima requisição, porque nada fora do seu próprio deploy lê esse HTML como dados. Uma resposta JSON de API é diferente assim que um cliente de fora a interpreta. Mude a forma, e todo cliente que ainda espera a antiga quebra, num ritmo que você não controla e em geral não vê chegar. Esta aplicação tem clientes assim: parceiros chamam os endpoints /partners/api/v1/... a partir dos próprios sistemas.
Uma mudança que parece pequena e não é
Pense num endpoint hipotético /api/v1/orders/42 que devolve:
{ "id": 42, "total": 19.99 }
O total é um Float em reais e centavos. Uma refatoração posterior passa o dinheiro para centavos inteiros em todo lugar, a correção comum para erros de arredondamento em código financeiro, e o mesmo endpoint passa a devolver:
{ "id": 42, "total_cents": 1999 }
Nada está errado por dentro; centavos inteiros corrigem uma classe real de bugs de arredondamento. Mas todo cliente externo que escreveu order.total.to_s agora lê nil onde havia um número, ou quebra por falta de uma chave. O bug não está no código novo, que saiu correto. Está na suposição de que "correto agora" e "compatível com o que já está por aí" são a mesma propriedade. Não são, e numa API essa diferença tem nome: uma mudança que quebra compatibilidade.
Quem sai prejudicado, e por que você não vê
O cliente de uma página HTML é um navegador com que você não precisa combinar nada: ele busca, renderiza, descarta e busca de novo. O cliente de uma API é código que outra pessoa escreveu e publicou, e ninguém lá está acompanhando os seus commits. Ele pode consultar a cada minuto por meses sem que ninguém mexa nele. A quebra não aparece na sua suíte de testes, no seu ambiente de homologação nem no seu rastreador de erros. Aparece nos logs deles, horas ou dias depois, e chega até você, se chegar, como um chamado de suporte que começa com "a API de vocês mudou".
O que o versionamento compra
Versionar não substitui código cuidadoso; a refatoração dos centavos acima foi cuidadosa e correta. É uma segunda promessa, explícita, por cima de "o código funciona": esta forma, acessada por este nome, continua significando o que já significa. /api/v1/orders/42 pode continuar devolvendo { "total": 19.99 } enquanto a v1 existir, e /api/v2/orders/42 devolve { "total_cents": 1999 } desde o dia em que sai. As duas estão corretas, e nenhuma precisa se dobrar à forma da outra. O resto deste curso trata da mecânica que sustenta essa divisão: na URL, num cabeçalho da requisição e no que o servidor renderiza quando sabe qual versão foi pedida.
Pontos-chave
- Uma resposta JSON de API é uma promessa de que um cliente depende. "Correto" e "compatível com o que já está publicado" são propriedades diferentes.
- O exemplo de float para centavos é uma forma comum de quebra: correta por dentro e incompatível por fora. É invisível para os seus testes, porque nada no seu código é o cliente que quebra.
- Um cliente de API em geral é código que você não controla nem vê rodando, como a integração de um parceiro. A quebra aparece nos logs de outra pessoa, no ritmo dela.
- Versionar é uma promessa explícita de que uma forma com nome mantém o significado. Assim uma forma nova, igualmente correta, pode sair com outro nome em vez de substituir a antiga debaixo dos clientes existentes.
Continue com a aula 2
Versionamento por URL: a forma que a maioria das apps Rails busca primeiro
Coloca a versão no caminho com namespaces aninhados, com controllers separados por versão e URLs visíveis e fáceis de guardar em cache.
Com uma conta grátis você também tem os quizzes, seu progresso e suas anotações, e a discussão.