Bereik

Grow

Manage

Automate

Bereik

Grow

Manage

Automate

RESTful API Versievormings Best Practices: Waarom v1 de #1 is

E-mail

1 min read

RESTful API Versievormings Best Practices: Waarom v1 de #1 is

E-mail

1 min read

RESTful API Versievormings Best Practices: Waarom v1 de #1 is

Dus hoe moeilijk kan het zijn om een API te versies? De waarheid is dat het niet moeilijk is, maar wat wel moeilijk is, is het behouden van enige gezond verstand door niet onnodig te vervallen in een duizelingwekkend aantal versies en subversies die worden toegepast over tientallen API-eindpunten met onduidelijke compatibiliteiten.

Breaking Changes Slecht! API Versioning Goed!

Naarmate iemand die een API heeft gebouwd of regelmatig gebruikt, sooner or later beseft, zijn brekende veranderingen erg slecht en kunnen ze een zeer ernstige smet zijn op een anders bruikbare API. Een brekende verandering is een wijziging in het gedrag van een API die de integratie van een gebruiker kan breken en resulteren in veel frustratie en verlies van vertrouwen tussen de API-aanbieder en gebruiker. Brekende veranderingen vereisen dat gebruikers vooraf worden geïnformeerd (met bijbehorende excuses) in plaats van een verandering die gewoon verschijnt, zoals een heerlijk nieuwe functie. De manier om die frustratie te vermijden, is door een versie van een API te maken met garanties van de API-eigenaar dat er geen verrassende veranderingen zullen worden geïntroduceerd in een enkele versie.




Dus hoe moeilijk kan het zijn om een API te versies? De waarheid is dat het dat niet is, maar wat moeilijk is, is om enige gezond verstand te behouden door niet nodeloos te vervallen in een duizelingwekkend aantal versies en subversies die worden toegepast over tientallen API-eindpunten met onduidelijke compatibiliteiten.




We introduceerden drie jaar geleden v1 van de API en realiseerden ons niet dat het tot op de dag van vandaag sterk zou blijven doorgaan. Dus hoe zijn we erin geslaagd om al meer dan twee jaar de beste e-mailbezorg-API te leveren en toch dezelfde API-versie te behouden? Hoewel er veel verschillende meningen zijn over hoe REST APIs te versioneren, hoop ik dat het verhaal van onze nederige maar krachtige v1 je kan begeleiden op je weg naar API-versie verlichting.

REST Is Best

De SparkPost API heeft zijn oorsprong toen we nog Message Systems waren, vóór onze avonturen in de cloud. Destijds waren we druk bezig met de laatste voorbereidingen voor de bèta-lancering van Momentum 4. Dit was een grote upgrade naar versie 3.x, onze marktleidende on-premise MTA. Momentum 4 omvatte een geheel nieuwe UI, real-time analytics, en bovenal een nieuwe web-API voor berichtinvoer en -generatie, het beheren van sjablonen, en het verkrijgen van e-mailstatistieken. Onze visie was een API-first architectuur – waarbij zelfs de UI zou communiceren met API-eindpunten.




Een van de eerste en beste beslissingen die we namen, was om een RESTful stijl aan te nemen. Sinds eind jaren 2000 zijn representational state transfer (REST) gebaseerde web-API's de de-facto standaard van cloud API's. HTTP en JSON gebruiken maakt het gemakkelijk voor ontwikkelaars, ongeacht welke programmeertaal ze gebruiken – PHP, Ruby en Java – om met onze API te integreren zonder kennis van of zorgen over onze onderliggende technologie.




Kiezen voor de RESTful architectuur was gemakkelijk. Kiezen voor een versiebeheerconventie was niet zo gemakkelijk. Aanvankelijk hebben we het vraagstuk van versiebeheer vooruitgeschoven door de bèta helemaal niet te versioneren. Echter, binnen enkele maanden was de bèta in handen van een paar klanten en begonnen we met de opbouw van onze clouddienst. Tijd voor versiebeheer. We evalueerden twee versiebeheerconventies. De eerste was om de versie direct in de URI te plaatsen en de tweede was om een Accept-header te gebruiken. De eerste optie is explicieter en minder gecompliceerd, wat makkelijker is voor ontwikkelaars. Aangezien we van ontwikkelaars houden, was het de logische keuze.

De SparkPost API heeft zijn oorsprong toen we nog Message Systems waren, vóór onze avonturen in de cloud. Destijds waren we druk bezig met de laatste voorbereidingen voor de bèta-lancering van Momentum 4. Dit was een grote upgrade naar versie 3.x, onze marktleidende on-premise MTA. Momentum 4 omvatte een geheel nieuwe UI, real-time analytics, en bovenal een nieuwe web-API voor berichtinvoer en -generatie, het beheren van sjablonen, en het verkrijgen van e-mailstatistieken. Onze visie was een API-first architectuur – waarbij zelfs de UI zou communiceren met API-eindpunten.




Een van de eerste en beste beslissingen die we namen, was om een RESTful stijl aan te nemen. Sinds eind jaren 2000 zijn representational state transfer (REST) gebaseerde web-API's de de-facto standaard van cloud API's. HTTP en JSON gebruiken maakt het gemakkelijk voor ontwikkelaars, ongeacht welke programmeertaal ze gebruiken – PHP, Ruby en Java – om met onze API te integreren zonder kennis van of zorgen over onze onderliggende technologie.




Kiezen voor de RESTful architectuur was gemakkelijk. Kiezen voor een versiebeheerconventie was niet zo gemakkelijk. Aanvankelijk hebben we het vraagstuk van versiebeheer vooruitgeschoven door de bèta helemaal niet te versioneren. Echter, binnen enkele maanden was de bèta in handen van een paar klanten en begonnen we met de opbouw van onze clouddienst. Tijd voor versiebeheer. We evalueerden twee versiebeheerconventies. De eerste was om de versie direct in de URI te plaatsen en de tweede was om een Accept-header te gebruiken. De eerste optie is explicieter en minder gecompliceerd, wat makkelijker is voor ontwikkelaars. Aangezien we van ontwikkelaars houden, was het de logische keuze.

De SparkPost API heeft zijn oorsprong toen we nog Message Systems waren, vóór onze avonturen in de cloud. Destijds waren we druk bezig met de laatste voorbereidingen voor de bèta-lancering van Momentum 4. Dit was een grote upgrade naar versie 3.x, onze marktleidende on-premise MTA. Momentum 4 omvatte een geheel nieuwe UI, real-time analytics, en bovenal een nieuwe web-API voor berichtinvoer en -generatie, het beheren van sjablonen, en het verkrijgen van e-mailstatistieken. Onze visie was een API-first architectuur – waarbij zelfs de UI zou communiceren met API-eindpunten.




Een van de eerste en beste beslissingen die we namen, was om een RESTful stijl aan te nemen. Sinds eind jaren 2000 zijn representational state transfer (REST) gebaseerde web-API's de de-facto standaard van cloud API's. HTTP en JSON gebruiken maakt het gemakkelijk voor ontwikkelaars, ongeacht welke programmeertaal ze gebruiken – PHP, Ruby en Java – om met onze API te integreren zonder kennis van of zorgen over onze onderliggende technologie.




Kiezen voor de RESTful architectuur was gemakkelijk. Kiezen voor een versiebeheerconventie was niet zo gemakkelijk. Aanvankelijk hebben we het vraagstuk van versiebeheer vooruitgeschoven door de bèta helemaal niet te versioneren. Echter, binnen enkele maanden was de bèta in handen van een paar klanten en begonnen we met de opbouw van onze clouddienst. Tijd voor versiebeheer. We evalueerden twee versiebeheerconventies. De eerste was om de versie direct in de URI te plaatsen en de tweede was om een Accept-header te gebruiken. De eerste optie is explicieter en minder gecompliceerd, wat makkelijker is voor ontwikkelaars. Aangezien we van ontwikkelaars houden, was het de logische keuze.

API Governance

Met een geselecteerde versieverzendingsconventie hadden we meer vragen. Wanneer zouden we de versie verhogen? Wat is een breaking change?  Zouden we de hele API of alleen bepaalde endpoints opnieuw versie geven? Bij SparkPost werken we met meerdere teams aan verschillende delen van onze API. Binnen die teams werken mensen op verschillende momenten aan verschillende endpoints. Daarom is het erg belangrijk dat onze API consistent is in het gebruik van conventies. Dit was groter dan versiebeheer.




We stelden een bestuursgroep samen, inclusief ingenieurs die elk team vertegenwoordigen, een lid van het Product Management-team en onze CTO. Deze groep is verantwoordelijk voor het vaststellen, documenteren en handhaven van onze API-conventies over alle teams heen. Een API-besturings Slack-kanaal is ook handig voor levendige debatten over het onderwerp.




De bestuursgroep heeft een aantal manieren geïdentificeerd waarop wijzigingen aan de API kunnen worden geïntroduceerd die gunstig zijn voor de gebruiker en geen breaking change vormen. Deze omvatten:




  • Een nieuwe resource of API-endpoint

  • Een nieuwe optionele parameter

  • Een wijziging aan een niet-openbaar API-endpoint

  • Een nieuwe optionele sleutel in de JSON POST-body

  • Een nieuwe sleutel die wordt geretourneerd in de JSON-responsbody




Omgekeerd omvatte een breaking change alles dat de integratie van een gebruiker kan verbreken, zoals:




  • Een nieuwe vereiste parameter

  • Een nieuwe vereiste sleutel in POST-bodies

  • Verwijdering van een bestaand endpoint

  • Verwijdering van een bestaande endpoint aanvraagmethode

  • Een materieel ander intern gedrag van een API-aanroep – zoals een wijziging in het standaardgedrag.

The Big 1.0

Naarmate we deze conventies documenteerden en bespraken, kwamen we ook tot de conclusie dat het in het belang van iedereen was (inclusief dat van ons!) om het maken van ingrijpende wijzigingen aan de API te vermijden, aangezien het beheren van meerdere versies nogal wat overhead met zich meebrengt. We besloten dat er een paar dingen waren die we moesten oplossen met onze API voordat we toewijden aan "v1".




Het verzenden van een eenvoudige e-mail vereiste veel te veel inspanning. Om "de eenvoudige dingen eenvoudig te houden" hebben we het POST-lichaam geüpdatet om ervoor te zorgen dat zowel eenvoudige als complexe gebruikssituaties worden gefaciliteerd. Het nieuwe formaat was ook meer toekomstbestendig. Ten tweede hebben we een probleem met het Metrics-eindpunt aangepakt. Dit eindpunt gebruikte een "group_by"-parameter die het formaat van het GET-response-lichaam zou veranderen, zodat de eerste sleutel de waarde van de groepsparameter zou zijn. Dat leek niet erg RESTful, dus we hebben elke groepsparameter in een apart eindpunt opgesplitst. Ten slotte hebben we elk eindpunt gecontroleerd en hier en daar kleine wijzigingen aangebracht om ervoor te zorgen dat ze voldeden aan de normen.

Nauwkeurige Documentatie

Het is belangrijk om nauwkeurige en bruikbare API-documentatie te hebben om breaking changes, van zowel opzettelijke als onbedoelde aard, te vermijden. We hebben besloten een eenvoudige API-documentatie aanpak te gebruiken met behulp van een Markdown-taal genaamd API Blueprint en onze documenten te beheren in Github. Onze gemeenschap draagt bij en verbetert deze open source documenten.  We behouden ook een niet-publieke set documenten in Github voor interne API's en eindpunten.




In het begin publiceerden we onze documenten naar Apiary, een geweldig hulpmiddel voor het prototypen en publiceren van API-documenten. Echter, het embedden van Apiary in onze website werkt niet op mobiele apparaten, dus gebruiken we nu Jekyll om in plaats daarvan statische documenten te genereren.  Onze nieuwste SparkPost API docs laden nu snel en werken goed op mobiele apparaten, wat belangrijk is voor ontwikkelaars die niet altijd achter hun computer zitten.

Deployment scheiden van Release

We leerden al vroeg de waardevolle truc van het scheiden van een implementatie van een release. Op deze manier is het mogelijk om vaak veranderingen door te voeren wanneer ze klaar zijn via continue levering en implementatie, maar we kondigen ze niet altijd publiekelijk aan of documenteren ze niet altijd tegelijkertijd. Het is niet ongewoon voor ons om een nieuwe API-endpoint te implementeren of een verbetering aan een bestaand API-endpoint te doen en deze te gebruiken binnen de UI of met interne tools voordat we het publiekelijk documenteren en ondersteunen. Op die manier kunnen we enkele aanpassingen doen voor bruikbaarheid of naleving van standaarden zonder ons zorgen te maken over het maken van een gevreesde breaking change. Zodra we tevreden zijn met de verandering voegen we het toe aan onze openbare documentatie.

Doh!

Het is alleen eerlijk om toe te geven dat er momenten zijn geweest waarop we onze idealen van 'geen breaking changes' niet hebben nageleefd en hiervan kunnen we leren. Op een gegeven moment besloten we dat het beter zou zijn voor gebruikers als een bepaalde eigenschap standaard op true zou staan in plaats van false. Nadat we de wijziging hadden doorgevoerd, ontvingen we verschillende klachten van gebruikers omdat het gedrag onverwacht was veranderd.  We hebben de wijziging teruggedraaid en een accountniveau-instelling toegevoegd - een veel gebruiksvriendelijkere benadering, zeker weten.




Af en toe worden we verleid om breaking changes in te voeren als resultaat van bugfixes. We besloten echter deze eigenaardigheden met rust te laten in plaats van het risico te lopen de integraties van klanten te verbreken voor de consistentie.




Er zijn zeldzame gevallen waarin we de serieuze beslissing hebben genomen om een breaking change door te voeren, zoals het afschaffen van een API-resource of -methode, in het belang van de bredere gebruikersgemeenschap en alleen nadat is bevestigd dat er weinig tot geen impact is op gebruikers. Bijvoorbeeld, we hebben bewust gekozen om het responsgedrag van de Suppression API te wijzigen, maar alleen na zorgvuldig de voordelen en gevolgen voor de gemeenschap af te wegen en de wijziging zorgvuldig aan onze gebruikers te communiceren. We zouden echter nooit een wijziging doorvoeren die de mogelijkheid heeft om rechtstreeks invloed te hebben op het verzenden van een productie-e-mail van een gebruiker.

Meld je aan voor onze nieuwsbrief.

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Meld je aan voor onze nieuwsbrief.

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Meld je aan voor onze nieuwsbrief.

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Pinterest-logo
Uber-logo
Square logo
Adobe-logo
Meta-logo
PayPal-logo

Bedrijf

Nieuwsbrief

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Uber-logo
Square logo
Adobe-logo
Meta-logo

Bedrijf

Nieuwsbrief

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.

Uber-logo
Adobe-logo
Meta-logo

Bereik

Grow

Manage

Automate

Bronnen

Bedrijf

Nieuwsbrief

Blijf op de hoogte met Bird via wekelijkse updates in je inbox.

Door te verzenden, ga je ermee akkoord dat Bird contact met je mag opnemen over onze producten en diensten.

U kunt zich op elk moment afmelden. Zie Bird's Privacyverklaring voor details over gegevensverwerking.