Când spargi API-urile fără avertisment, spargi încrederea
TL;DR: Ar trebui să vă versiuneați API-urile pentru a preveni ruperea clienților existenți atunci când efectuați modificări.
TL;DR: Ar trebui să vă versiuneați API-urile pentru a preveni ruperea clienților existenți atunci când efectuați modificări.
Probleme
- Aplicațiile clienților se prăbușesc
- Eșecuri de integrare
- Încălcarea principiului surprizei minime
- Downtime
- Încredere ruptă
- Rollerback-uri de implementare necesare
- Timpul de dezvoltare pierdut
- Degradarea experienței utilizatorului
Soluții
- Adaugă versiune semantică
- Compatibilitate retroactivă
- Crearea avertismentelor de depreciere
- Crearea de roadmaps
- Utilizați Negocierea conținutului
- Versiuni paralele
- Comunicați schimbările mai devreme
- Deteriorarea caracteristicilor treptat
- Documentul care încalcă modificările în mod clar
- Verificați parametrii deprecați cu logging
- Testarea completă a noilor versiuni
- Eliminarea funcționalității depreciate după apusul soarelui
Contextul
Atunci când modificați API-urile fără versiuni corespunzătoare, creați modificări disruptive care afectează toți clienții existenți.
Forțați consumatorii să-și actualizeze imediat codul sau să se confrunte cu defecțiuni ale sistemului.
Încălcați contractul implicit dintre furnizorii API și consumatori.
Software-ul modern se bazează în mare măsură pe stabilitatea API, iar introducerea de modificări fără avertisment poate crea eșecuri în cascadă între sistemele dependente.
Acest lucru este mai important astăzi decât oricândmulte IA-uri își construiesc soluțiile folosind documentația API existentă.
Atunci când actualizați un API fără a menține compatibilitatea retroactivă, riscați să întrerupeți toate aplicațiile care depind de acesta.
Acest lucru creează instabilitate, frustrare și reparații costisitoare pentru utilizatori.
Clienții adesea tolereazădefectelorîn funcționalități noi, dar niciodată un comportament stabil anterior rupt.
Versiunea corectă asigură tranziții netede și menține fiabilitatea sistemului.
Sample Cod
greșită 🙂
// user-api-v1.json - Original API response
{
"id": 317,
"name": "Mr Nimbus",
"email": "nimbus@atlantis.com",
"nationalities": "Brazilian,Canadian,Oceanic"
}
// Later changed to this without versioning:
{
"userId": 317,
"fullName": "Mr Nimbus",
"emailAddress": "nimbus@atlantis.com",
"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;
});
Dreaptă 🙂
// user-api-v1.json - Version 1 (maintained)
{
"id": 317,
"name": "Mr Nimbus",
"email": "nimbus@atlantis.com",
"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": "nimbus@atlantis.com",
"emailAddress": "nimbus@atlantis.com",
"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": "nimbus@atlantis.com",
"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ţie
- [x] Semiautomată
Puteți detecta acest miros atunci când găsiți API-uri care schimbă numele câmpurilor, elimină câmpurile sau modifică structurile de date fără a menține compatibilitatea retroactivă.
Căutați aplicații client care se rupe după implementările API.
Verificați pentru capetele de versiune lipsă sau schemele de versiune URL.
Monitorizează jurnalele de eroare pentru vârfurile bruște ale eșecurilor clientului după lansări.
️ ️
- apei
Nivel
- [x] Între timp
De ce este importantă mișcarea ️
Trebuie să păstrați o poziție stabilăHartaîntre contractul dvs. API și așteptările clienților.
Când vei rupe acestBijeciiPrin schimbarea API-ului fără versiune, încălcați principiul fundamental că clienții se pot baza pe interfețe coerente.
Creați o neconcordanță între ceea ce clienții se așteaptă să primească și ceea ce oferă API-ul dvs.
Acest lucru rupe corespondența unu-la-unu între promisiunile API și livrarea API, ducând la eșecuri de sistem și pierderea încrederii.
Când rupeți cartografierea între API-ul dvs. și logica de afaceri pe care o reprezintă, clienții nu pot interacționa în mod fiabil cu sistemul dvs.
Această neconcordanță duce la defecte, timp de oprire, lipsă de încredere și o experiență slabă a utilizatorului.
Generația
Generatoarele AI creează adesea acest miros atunci când le cereți să "îmbunătățească" sau să "actualizeze" API-urile existente.
Ei se concentrează pe a face API-ul "mai bun" fără a lua în considerare compatibilitatea retroactivă.
Trebuie să instruiți în mod explicit instrumentele AI să mențină numele de câmp existente și să adăugați versiuni atunci când efectuați modificări.
Adesea preferă designul curat asupra stabilității, cu excepția cazului în careexplicitA spus altfel.
Detecție
Generatoarele AI pot corecta acest miros atunci când oferiți instrucțiuni clare despre strategiile de versiune API.
Ar trebui să le cereți să implementeze versiunea semantică, să mențină compatibilitatea retroactivă și să creeze căi de migrare pentru caracteristicile depreciate.
Încercați!
Amintiți-vă: Asistenții AI fac multe greșeli
Prompt sugerat: Creați versiuni API pentru a preveni modificările de rupere
Prompt sugerat: Creați versiuni API pentru a preveni modificările de rupere
Without Proper Instructions |
With Specific Instructions |
---|---|
Concluzie
Ar trebui să vă versionați întotdeauna API-urile pentru a preveni modificările care afectează aplicațiile client.
Chiar şi din prima versiune.
Atunci când mențineți contracte stabile prin versiuni adecvate, vă construiți încrederea cu consumatorii API și permiteți evoluția fără probleme a sistemelor.
Schimbările sunt inevitabile, dar nu ar trebui să vă distrugă clienții.
Versiunează-ți întotdeauna API-urile, dezactivă-te cu atenție și comunică proactiv pentru a evita întreruperile inutile.
Relații
https://hackernoon.com/misusing-http-status-codes-wrecks-your-api-monitoring-and-client-logic
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-iv-7sc3w8n
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xii
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxii
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxiv
https://hackernoon.com/how-to-find-the-stinky-parts-of-your-code-part-xxxv
Disclaimer
Mirosurile sunt ale meleOpinia.
Credite
Fotografie deGiancarlo RevolledoesteUnsplash
API-urile sunt pentru totdeauna, așa că proiectați-le cu grijă
API-urile sunt pentru totdeauna, așa că proiectați-le cu grijă
Martin Fowler
Acest articol face parte din seria CodeSmell.