Bästa praxis för versionering av RESTful API: Varför v1 är #1

Bästa praxis för versionering av RESTful API: Varför v1 är #1

Bästa praxis för versionering av RESTful API: Varför v1 är #1

May 24, 2017

Publicerad av

Publicerad av

Chris McFadden

Chris McFadden

Kategori:

Kategori:

E-post

E-post

Ready to see Bird
in action?

Ready to see Bird
in action?

RESTful API Versioning Best Practices: Why v1 is #1

Breaking Changes Bad!  API Versioning Good!

Alla som har byggt eller regelbundet använder ett API inser förr eller senare att "breaking changes" är mycket dåliga och kan vara en mycket allvarlig fläck på ett annars användbart API. En "breaking change" är en ändring av ett API:s beteende som kan förstöra en användares integration och leda till mycket frustration och förlorat förtroende mellan API-leverantören och användaren. Förändringar som leder till avbrott kräver att användarna meddelas i förväg (med åtföljande mea culpas) snarare än en förändring som bara dyker upp, till exempel en förtjusande ny funktion. Sättet att undvika denna frustration är att versionera ett API med garantier från API-ägaren att det inte kommer att introduceras några överraskande förändringar inom en enda version.


Så hur svårt kan det vara att versionera ett API? Sanningen är att det inte är det, men det som är svårt är att behålla lite förnuft genom att inte i onödan utvecklas till ett svindlande antal versioner och subversioner som tillämpas över dussintals API-slutpunkter med oklar kompatibilitet.


We introduced v1 of the API three years ago and did not realize that it would be going strong to this day. So how have we continued to provide the best email delivery API for over two years but still maintain the same API version? While there are many olika åsikter on how to version REST API:er, I hope that the story of our humble yet powerful v1 might guide you on your way to API versioning enlightenment.


REST är bäst

SparkPost API härstammar från när vi var Message Systems, innan våra äventyr i molnet. Vid den tiden höll vi på med de sista förberedelserna inför betalanseringen av Momentum 4. Detta var en stor uppgradering av version 3.x, vår marknadsledande lokala MTA. Momentum 4 innehöll ett helt nytt användargränssnitt, realtidsanalys och framför allt ett nytt webb-API för att injicera och generera meddelanden, hantera mallar och få mätvärden för e-post. Vår vision var en API first-arkitektur - där även användargränssnittet skulle interagera med API-slutpunkter.


One of the earliest and best decisions we made was to adopt a RESTful style. Since the late 2000s representational state transfer (REST) based web APIs are the de-facto standard of cloud APIs. Using HTTP and JSON makes it easy for developers, regardless of which programming language they use – PHP, Ruby, and Java – to integrate with our API without knowing or caring about our underlying technology.


Choosing to use the RESTful architecture was easy. Choosing a versioning convention was not so easy. Initially we punted on the question of versioning by not versioning the beta at all. However, within a couple months the beta was in the hands of a few customers and we began building out our cloud service.  Time to version. We evaluated two versioning conventions. Den first was to put the versioning directly in the URI and the second was to use an Accept header. Den first option is more explicit and less complicated, which is easier for developers.  Since we love developers, it was the logical choice.


API-styrning

With a versioning convention selected we had more questions. When would we bump the version? What is a breaking change?  Would we reversion the whole API or just certain endpoints? At SparkPost, we have multiple teams working on different parts of our API. Within those teams, people work on different endpoints at different times. Therefore, it’s very important that our API is consistent in the use of conventions. This was bigger than versioning.


We established a governance group including engineers representing each team, a member of the Product Management team, and our CTO. This group is responsible for establishing, documenting, and enforcing our API conventions across all teams. An API governance Slack channel also comes in handy for lively debates on the topic.


Styrgruppen identifierade ett antal sätt att införa förändringar i API:et som är till nytta för användaren och som inte utgör en genomgripande förändring. Dessa inkluderar följande:


  • En ny resurs eller API-slutpunkt

  • En ny valfri parameter

  • En ändring av en icke-offentlig API-slutpunkt

  • En ny valfri nyckel i JSON POST-kroppen

  • En ny nyckel som returneras i JSON-svarskroppen


Omvänt inkluderade en "breaking change" allt som kunde förstöra en användares integration, t.ex:


  • En ny nödvändig parameter

  • En ny nödvändig nyckel i POST-organ

  • Borttagning av en befintlig ändpunkt

  • Borttagning av en befintlig ändpunkt request method

  • Ett väsentligt annorlunda internt beteende för ett API-anrop - t.ex. en ändring av standardbeteendet.


Den stora 1.0

När vi dokumenterade och diskuterade dessa konventioner kom vi också fram till att det var i allas intresse (inklusive vårt!) att undvika att göra genomgripande ändringar i API:et eftersom det innebär en hel del overhead att hantera flera versioner. Vi bestämde att det fanns några saker som vi borde fixa med vårt API innan vi gick över till "v1".


Sending a simple email required way too much effort.  To “keep the simple things simple” we updated the POST body to ensure that both simple and complex use cases are accommodated.  The new format was more future-proof as well.  Secondly we addressed a problem with the Metrics endpoint. This endpoint used a “group_by” parameter that would change the format of the GET response body such that the first key would be the value of the group by parameter. That did not seem very RESTful so we broke each group by into a separate endpoint. Finally we audited each endpoint and made minor changes here and there to ensure they conformed with the standards.


Korrekt dokumentation

It is important to have accurate and usable API documentation to avoid breaking changes, of the deliberate or unintentional kind. We decided to use a simple API documentation approach leveraging a Markdown language called API-struktur and hantera våra dokument i Github. Our community contributes and improves upon these open source docs.  We also maintain a nonpublic set of docs in Github for internal APIs and endpoints.


Initially, we published our docs to Apiary, a great tool for prototyping and publishing API docs. However, embedding Apiary into our website doesn’t work on mobile devices so we now use Jekyll to generate static docs instead.  Our latest Dokument för SparkPost API now load quickly and work well on mobile devices which is important for developers who are not always sitting at their computer.


Separera driftsättning från lansering

Vi lärde oss tidigt det värdefulla knepet att skilja en driftsättning från en release. På så sätt är det möjligt att ofta distribuera ändringar när de är redo genom kontinuerlig leverans och distribution, men vi tillkännager eller dokumenterar dem inte alltid offentligt samtidigt. Det är inte ovanligt att vi distribuerar en ny API-slutpunkt eller en förbättring av en befintlig API-slutpunkt och använder den i användargränssnittet eller med interna verktyg innan vi offentligt dokumenterar den och stöder den. På så sätt kan vi göra några justeringar för användbarhet eller överensstämmelse med standarder utan att oroa oss för att göra en fruktad brytande ändring. När vi är nöjda med ändringen lägger vi till den i vår offentliga dokumentation.


Doh!

It is only fair to admit that there have been times where we have not lived up to our “no breaking changes” ideals and these are worth learning from. On one occasion we decided it would be better for users if a certain property defaulted to true instead of false. After we deployed the change we received several complaints from users since the behavior had changed unexpectedly.  We reverted the change and added an account level setting – a much more user friendly approach for sure.


Ibland är vi frestade att införa genomgripande ändringar som ett resultat av buggfixar. Vi har dock beslutat att låta dessa idiosynkrasier vara i fred i stället för att riskera att bryta kundernas integrationer för konsekvensens skull.


There are rare cases where we made the serious decision to make a breaking change – such as deprecating an API resource or method – in the interest of the greater user community and only after confirming that there is little to no impact to users. For example, we deliberately made the choice to alter the response behavior of the Suppression API but only after carefully weighing the benefits and impacts till community and carefully communicating the change to our users. However, we would never introduce a change that has a remote possibility of directly impacting the sending of a user’s production email.

Your new standard in Marketing, Betalningar & Sales. It's Bird

The right message -> till right person -> vid right time.

By clicking "See Bird" you agree to Bird's Meddelande om integritet.

Your new standard in Marketing, Betalningar & Sales. It's Bird

The right message -> to the right person -> vid right time.

By clicking "See Bird" you agree to Bird's Meddelande om integritet.