Quando você quebra as APIs sem aviso, você quebra a confiança
TL; DR: Você deve fazer uma versão para impedir que a quebra de clientes existentes quando fizer alterações.
Problemas 😔
- Os aplicativos do cliente travam
- Falhas de integração
- Violação de princípio de surpresa menos mínima
- Tempo de inatividade
- Confiança quebrada
- Rollacks de implantação necessárias
- Tempo de desenvolvimento desperdiçado
- Degradação da experiência do usuário
Soluções 😃
- Adicione versão semântica
- Implementar compatibilidade com versões anteriores
- Crie avisos de depreciação
- Crie roteiros
- Use a negociação de conteúdo
- Manter versões paralelas
- Comunicar mudanças mais cedo
- Depreciar os recursos gradualmente
- Documentar as mudanças claramente
- Verifique os parâmetros depreciados com o registro
- Teste novas versões completamente
- Remova a funcionalidade depreciada após o pôr do sol
Contexto 💬
Quando você modifica as APIs sem versão adequada, você cria alterações de ruptura que afetam todos os clientes existentes.
Você força os consumidores a atualizar o código imediatamente ou enfrentar falhas do sistema.
Você quebra o contrato implícito entre provedores de API e consumidores.
O software moderno depende muito da estabilidade da API e a introdução de mudanças de ruptura sem aviso pode criar falhas em cascata nos sistemas dependentes.
Isso é mais importante hoje do que nunca, já que muitos IAS constroem suas soluções usando a documentação da API existente.
Ao atualizar uma API sem manter a compatibilidade com versões anteriores, você corre o risco de quebrar todos os aplicativos que dependem dela.
Isso cria instabilidade, frustração e correções caras para os usuários.
Os clientes geralmente toleram defeitos em novas funcionalidades, mas nunca um comportamento anteriormente estável quebrado.
A versão adequada garante transições suaves e mantém a confiabilidade do seu sistema.
Código de exemplo 📖
Errado ❌
// user-api-v1.json - Original API response
{
"id": 317,
"name": "Mr Nimbus",
"email": "[email protected]",
"nationalities": "Brazilian,Canadian,Oceanic"
}
// Later changed to this without versioning:
{
"userId": 317,
"fullName": "Mr Nimbus",
"emailAddress": "[email protected]",
"createdAt": "2018-12-09T18:30:00Z",
"nationalities": ["Brazilian", "Canadian", "Oceanic"]
}
fetch('/api/users/317')
.then(response => response.json())
.then(user => {
// This breaks when API changes field names and data types
document.getElementById('name').textContent = user.name;
document.getElementById('email').textContent = user.email;
// This breaks when nationalities changes from string to array
document.getElementById('nationalities').textContent
= user.nationalities;
});
Direita 👉
// user-api-v1.json - Version 1 (maintained)
{
"id": 317,
"name": "Mr Nimbus",
"email": "[email protected]",
"nationalities": "Brazilian,Canadian,Oceanic"
}
// user-api-v2.json - Version 2
// (new structure, backward compatible)
{
"id": 317,
"userId": 317,
"name": "Mr Nimbus",
"fullName": "Mr Nimbus",
"email": "[email protected]",
"emailAddress": "[email protected]",
"createdAt": "2018-12-09T18:30:00Z",
"nationalities": "Brazilian,Canadian,Oceanic"
"nationalitiesList": ["Brazilian", "Canadian", "Oceanic"]
}
// user-api-v3.json - Version 3
// (new structure, backward not compatible)
{
"userId": 317,
"fullName": "Mr Nimbus",
"emailAddress": "[email protected]",
"createdAt": "2018-12-09T18:30:00Z",
"nationalitiesList": ["Brazilian", "Canadian", "Oceanic"]
}
// client-code-versioned.js
const API_VERSION = 'v1';
fetch(`/api/${API_VERSION}/users/317`)
.then(response => response.json())
.then(user => {
document.getElementById('name').textContent = user.name;
document.getElementById('email').textContent = user.email;
// V1 handles comma-separated string
document.getElementById('nationalities').textContent
= user.nationalities;
});
// Or with content negotiation
fetch('/api/users/317', {
headers: {
'Accept': 'application/vnd.api+json;version=1'
}
})
.then(response => response.json())
.then(user => {
document.getElementById('name').textContent = user.name;
document.getElementById('email').textContent = user.email;
document.getElementById('nationalities').textContent
= user.nationalities;
});
Detecção 🔍
Você pode detectar esse cheiro quando encontrar APIs que alteram os nomes dos campos, removem campos ou alteram as estruturas de dados sem manter a compatibilidade com versões anteriores.
Procure aplicativos de clientes que quebrem após as implantações da API.
Verifique os cabeçalhos da versão ausente ou os esquemas de versão URL.
Monitore os logs de erros para picos repentinos nas falhas do cliente após as liberações.
Nível 🔋
Por que a bijeção é importante 🗺️
Você deve manter um mapeador estável entre o contrato da API e as expectativas do cliente.
Ao quebrar essa bijeção alterando a API sem versões, você viola o princípio fundamental de que os clientes podem confiar em interfaces consistentes.
Você cria uma incompatibilidade entre o que os clientes esperam receber e o que sua API fornece.
Isso quebra a correspondência individual entre as promessas da API e a entrega da API, levando a falhas do sistema e perda de confiança.
Modelo de APIs Serviços do mundo real. Quando você quebra o mapeamento entre sua API e a lógica de negócios que ela representa, os clientes não podem interagir com segurança com o seu sistema.
Essa incompatibilidade leva a defeitos, tempo de inatividade, falta de confiança e uma má experiência do usuário.
Geração ai 🤖
Os geradores de IA geralmente criam esse cheiro quando você pede que eles “melhorem” ou “atualizem” as APIs existentes.
Eles se concentram em tornar a API “melhor” sem considerar a compatibilidade com versões anteriores.
Você precisa instruir explicitamente as ferramentas de IA para manter os nomes de campo existentes e adicionar versionamento ao fazer alterações.
Eles geralmente favorecem o design limpo sobre a estabilidade, a menos que explicitamente contado de outra forma.
Detecção de IA 🧲
Os geradores de IA podem consertar esse cheiro quando você fornece instruções claras sobre estratégias de versão da API.
Você deve solicitar que eles implementem versões semânticas, mantenham compatibilidade com versões anteriores e criem caminhos de migração para os recursos depreciados.
Experimente eles! 🛠
Lembre -se: os assistentes de IA cometem muitos erros
Prompt sugerido: Crie um versão da API para impedir a quebra de mudanças
Conclusão 🏁
Você sempre deve fazer uma versão das suas APIs para impedir que as mudanças de quebra de impacto no impacto dos clientes.
Mesmo da sua primeira versão.
Quando você mantém contratos estáveis por meio de versões adequadas, você cria confiança com os consumidores da API e permite a evolução suave de seus sistemas.
As mudanças de quebra são inevitáveis, mas não devem quebrar seus clientes.
Sempre faça uma versão das suas APIs, deprecie cuidadosamente e comunique -se proativamente para evitar interrupções desnecessárias.
Relações 👩❤️💋👨
Isenção de responsabilidade 📘
Os cheiros de código são minha opinião.
Créditos 🙏
Foto de Giancarlo Revolledo no Unsplash
APIs são para sempre, então projete -as com cuidado
Martin Fowler
Este artigo faz parte da série CodesMell.