API-wijzigingen

Hoe deprecieer je een API zonder developers te verliezen

6 min lezen

Een API deprecieren is aankondigen dat iets vandaag nog werkt en op een genoemde datum stopt met werken, en dan beide helften van die belofte houden. De meeste deprecaties falen op de tweede helft: de datum verschuift stilletjes, of hij komt en de aanroepers die de aankondiging nooit zagen horen het van een fout. Een deprecatie is af wanneer elke getroffen aanroeper is gemigreerd of, individueel, te horen heeft gekregen dat dat niet zo is.

Wat is API-deprecatie?

Deprecatie is de periode tussen het aankondigen dat een endpoint, veld of versie gaat verdwijnen en het daadwerkelijk verwijderen ervan. Tijdens die periode blijft het oude gedrag werken, zegt de documentatie dat het weggaat, en draagt elk antwoord een machineleesbare waarschuwing. Verwijdering is het aparte, latere moment, vaak sunset genoemd. De twee worden door elkaar gehaald, en die verwarring is waar de schade gebeurt: “deprecated” begint “misschien al weg” te betekenen, en aanroepers vertrouwen geen van beide woorden meer.

TermBetekenisWaar aanroepers op kunnen rekenen
DeprecatedAangekondigd als verdwijnend, werkt nogVolledig gedrag tot de sunset-datum
SunsetDe datum waarop het stopt met werkenNiets na deze datum
Retired / verwijderdWeg; verzoeken falenEen fout, idealiter een die de vervanging noemt
LegacyOngedefinieerd. Vermijd het woordNiets, wat het probleem is

Hoe lang zou een deprecatieperiode moeten duren?

Lang genoeg voor een aanroeper om erachter te komen en het werk te doen, gemeten vanaf wanneer de aankondiging hem bereikte in plaats van vanaf wanneer jullie hem schreven. Negentig dagen is de gangbare ondergrens voor een publieke web-API. Twaalf maanden is normaal voor alles wat is ingebed in software die eindgebruikers installeren, omdat de fix ook door hun releaseproces moet. Googles versioneringsrichtlijn, AIP-185, vraagt om een redelijke overgangsperiode en raadt 180 dagen aan, zelfs voordat bètafunctionaliteit wordt verwijderd, en Kubernetes documenteert zijn deprecatiebeleid in aantal releases in plaats van maanden, wat de juiste eenheid is wanneer jullie aanroepers per versie updaten.

Kies een periode, schrijf hem vast als beleid, en stop met hem per verandering te beslissen. Een gepubliceerd beleid maakt van elke deprecatie een regeltoepassing in plaats van een onderhandeling.

Het deprecatiebeleid vastleggen dekt het begin van het venster; een API-versie uitfaseren behandelt het aparte bericht dat nodig is aan het einde, wanneer de periode daadwerkelijk afloopt en de versie stopt met werken.

Het deprecatieschema

Vier datums, samen op dag één aangekondigd. Elk is een aparte changelog-entry bij aankomst, dus het verhaal wordt vier keer verteld aan iedereen die alleen de changelog leest.

  1. Aankondigen. De entry zegt wat wordt gedeprecieerd, waarom, wat het vervangt, en de sunset-datum. De documentatie voor het oude ding krijgt een banner die naar de migratie linkt. Antwoorden krijgen de hieronder beschreven headers.
  2. Herinneren, halverwege. Een tweede entry, en een direct bericht aan elke aanroeper die het oude gedrag nog gebruikt. Dit is de stap die gebruiksdata nodig heeft: als jullie niet kunnen opsommen wie het gedeprecieerde endpoint nog aanroept, kunnen jullie het niet doen, en dat is de moeite waard om op te lossen voor de volgende deprecatie.
  3. Brownout, kort voor de datum. Geef fouten terug voor het oude gedrag gedurende een kort venster, een uur of een dag, en herstel het dan. Aanroepers die elke aankondiging misten ontdekken het nu, terwijl er nog tijd is. GitHub gebruikte geplande brownouts voordat het wachtwoordauthenticatie voor de API afschafte, en het is de effectiefste enkele stap in deze lijst.
  4. Sunset. Verwijder het. De fout die het vervangt noemt de vervanging en linkt naar de migratiegids. Houd de fout lange tijd op zijn plek; een 404 vertelt een aanroeper niets.

Wat zou een deprecatiebericht moeten zeggen?

Een deprecatiebericht zegt wat weggaat, wanneer het stopt, wat in plaats daarvan te gebruiken, en wie het treft. Hier is de vorm, ingevuld:

GET /v1/reports/daily is gedeprecieerd en stopt met werken op 1 maart 2027. Het wordt vervangen door GET /v2/reports?granularity=day, dat dezelfde data teruggeeft met een stabiel schema en paginering. Treft de 214 integraties die het v1-endpoint de afgelopen 30 dagen aanriepen; als de jouwe daar één van is, ontvang je dit bericht ook per e-mail. Migratiegids: [link]. Er verandert niets tot 1 maart 2027. Vanaf die datum geeft het v1-endpoint 410 Gone terug met een link naar deze entry.

Elke zin draagt iets waar de lezer behoefte aan heeft. Het aantal getroffen integraties vertelt elke lezer of ze moet blijven lezen. “Er verandert niets tot” is de zin die degenen die niet getroffen zijn het tabblad laat sluiten. De pagina changelog-voorbeelden verzamelt entries van teams die deze vorm consequent schrijven, en het is de moeite waard om er drie te lezen voordat je je eigen eerste schrijft.

Welke headers zou een gedeprecieerd endpoint moeten sturen?

Stuur Deprecation, Sunset en een Link naar de opvolger, op elk antwoord van het gedeprecieerde endpoint, vanaf de dag van de aankondiging. De Deprecation-header draagt de datum waarop de deprecatie inging; de Sunset-header draagt de datum waarop het endpoint stopt met antwoorden; Link: <url>; rel="successor-version" wijst naar wat in plaats daarvan te gebruiken.

HTTP/1.1 200 OK
Deprecation: @1756425600
Sunset: Mon, 01 Mar 2027 00:00:00 GMT
Link: <https://api.example.com/v2/reports>; rel="successor-version"
Link: <https://example.com/changelog/daily-reports>; rel="deprecation"

De meeste aanroepers zullen de headers zelf nooit lezen. Hun waarde zit erin dat de HTTP-client, gateway of monitoring van een aanroeper dat wel kan, wat jullie deprecatie verandert in een alert aan hun kant in plaats van een pagina aan de jullie kant. SDK’s die jullie leveren zouden een waarschuwing moeten loggen wanneer ze er een zien.

Wie is ingelicht, en hoe weten jullie dat?

Dit is de stap die beslist of de sunset rustig verloopt of een supportincident wordt, en het is de lastigste om alleen met een changelog te doen. Een changelog-entry licht iedereen in die de changelog leest. Een deprecatie moet de specifieke mensen bereiken wier code gaat falen, en de gebruikelijke manier om ze te vinden is dezelfde gebruiksdata die de halverwege-herinnering nodig heeft: de API-sleutels, apps of accounts die het gedeprecieerde gedrag recent aanriepen.

De loop die wij draaien: de entry wordt opgesteld uit de pull request die de deprecatie toevoegt, een mens beoordeelt de formulering en de datum, en zodra hij is gepubliceerd is de entry zelf de notificatie. Iedereen wiens widgetfeedback over het probleem, of verzoek om de vervanging, een GitHub-issue werd dat de pull request sluit, krijgt een reactie op dat issue dat het is uitgebracht, met een link naar de entry. Feed en widget bedienen dezelfde entry aan iedereen anders, samen met elke andere entry in de API-changelog. Wat we niet doen is de deprecatie “uitgebracht” laten worden voordat een mens hem heeft gepubliceerd; een bericht met de verkeerde datum is erger dan geen bericht.

Wat jullie tooling ook is, de vraag die je op sunset-dag moet kunnen beantwoorden is: welke aanroepers gebruikten dit vorige week nog, en wie van hen hebben we direct verteld? Als het antwoord “we hebben erover gepost” is, is de sunset niet klaar.

Wat is het verschil tussen deprecieren en versioneren?

Versioneren is hoe je het oude gedrag beschikbaar houdt terwijl het nieuwe bestaat; deprecatie is hoe je het oude met pensioen stuurt. Een nieuwe API-versie zonder deprecatiebeleid voor de vorige is een belofte om beide voor altijd te draaien. Een deprecatie zonder versionering is een breaking change met vertraging. Jullie hebben beide nodig, en de versie is de makkelijkere helft. GraphQL is de uitzondering die het waard is om te noemen: meestal is er helemaal geen versienummer om te verhogen, en GraphQL-schemadeprecatie behandelt hoe één gedeeld schema in plaats daarvan een veld met een directive met pensioen stuurt.

FAQ

Zou een gedeprecieerd endpoint precies zo moeten blijven werken als voorheen? Ja, tot de sunset-datum. De enige toegestane veranderingen zijn de toegevoegde headers en, tegen het eind, een geplande brownout die jullie van tevoren aankondigden.

Welke statuscode zou een met pensioen gestuurd endpoint moeten teruggeven? 410 Gone, met een body en een Link-header naar de vervanging en de changelog-entry. 404 zegt dat de URL nooit heeft bestaan, wat onwaar en onbehulpzaam is.

Kan een deprecatieperiode worden ingekort? Alleen voor security. Als het oude gedrag uitbuitbaar is, zeg dat, kort de periode in, en vertel elke getroffen aanroeper direct in plaats van te vertrouwen op de changelog.

Moet ik een veld deprecieren, of alleen hele endpoints? Velden, parameters, enum-waarden, standaardwaarden en headers hebben allemaal dezelfde behandeling nodig, omdat elk een correcte aanroeper kan breken. Een verwijderd veld is de meest voorkomende deprecatie en de meest overgeslagen.


De technische beweringen in dit artikel zijn niet onafhankelijk gecontroleerd. Klopt er iets niet, laat het ons weten, dan corrigeren we het.

Meer op changeloop: Documentatie voor ontwikkelaars, Changelog-voorbeelden

changeloop
Het team achter een changelog die de cirkel rondmaakt. Je gebruikers vragen iets, je team levert het, degene die het vroeg hoort ervan.