Zasięg

Grow

Manage

Automate

Zasięg

Grow

Manage

Automate

Najlepsze praktyki wersjonowania RESTful API: Dlaczego v1 jest numerem 1

Chris McFadden

24 maj 2017

Email

1 min read

Najlepsze praktyki wersjonowania RESTful API: Dlaczego v1 jest numerem 1

Chris McFadden

24 maj 2017

Email

1 min read

Najlepsze praktyki wersjonowania RESTful API: Dlaczego v1 jest numerem 1

Jak trudne może być wersjonowanie API? Prawda jest taka, że nie jest to trudne, ale to, co jest trudne, to utrzymanie pewnej zdroworozsądkowej perspektywy, aby nie bezsensownie zbaczać w oszałamiającą liczbę wersji i podwersji stosowanych w dziesiątkach punktów końcowych API o niejasnych kompatybilnościach.

Złe zmiany! API Versioning dobre!

Jak każdy, kto budował lub regularnie korzysta z API, zdaje sobie sprawę prędzej czy później, że zmiany wprowadzające niezgodność są bardzo złe i mogą być bardzo poważną skazą na inaczej użytecznym API. Zmiana wprowadzająca niezgodność to zmiana w zachowaniu API, która może złamać integrację użytkownika i prowadzić do wielu frustracji oraz utraty zaufania między dostawcą API a użytkownikiem. Zmiany te wymagają, aby użytkownicy byli powiadamiani z wyprzedzeniem (z towarzyszącymi przeprosinami) zamiast zmiany, która po prostu się pojawia, jak np. nowa, zachwycająca funkcja. Sposobem na uniknięcie tej frustracji jest wersjonowanie API z zapewnieniami od właściciela API, że w żadnej z wersji nie zostaną wprowadzone zaskakujące zmiany.

Więc jak trudne może być wersjonowanie API? Prawda jest taka, że nie jest to trudne, ale trudne jest utrzymanie zdrowego rozsądku, nie wpadając niepotrzebnie w oszałamiającą liczbę wersji i podwersji stosowanych w dziesiątkach punktów końcowych API z niejasnymi zgodnościami.

Wprowadziliśmy wersję v1 API trzy lata temu i nie zdawaliśmy sobie sprawy, że będzie działać tak dobrze aż do dziś. Jak więc udało nam się dalej dostarczać najlepsze API do dostarczania email nawet przez dwa lata, zachowując tę samą wersję API? Ta stabilność jest kluczowa dla deweloperów budujących aplikacje wykorzystujące API email w infrastrukturze chmurowej, gdzie niezawodność i spójność są najważniejsze. Chociaż istnieje wiele różnych opinii na temat wersjonowania REST API, mam nadzieję, że historia naszej skromnej, lecz potężnej wersji v1 może poprowadzić Cię na drodze do oświecenia w wersjonowaniu API.

REST Is Best

API SparkPost wywodzi się z czasów, gdy byliśmy Message Systems, przed naszymi przygodami w chmurze. W tym czasie byliśmy zajęci końcowymi przygotowaniami do uruchomienia wersji beta Momentum 4. Była to istotna aktualizacja wersji 3.x, naszego wiodącego na rynku lokalnego MTA. Momentum 4 obejmowała całkowicie nowy interfejs użytkownika, analizę w czasie rzeczywistym i co najważniejsze, nowe web API do wstrzykiwania i generowania wiadomości, zarządzania szablonami oraz uzyskiwania metryk emailowych. Naszą wizją była architektura oparta na API – gdzie nawet interfejs użytkownika wchodziłby w interakcję z punktami końcowymi API.

Jedną z najwcześniejszych i najlepszych decyzji, jakie podjęliśmy, było przyjęcie stylu RESTful. Od późnych lat 2000 przenoszenie stanu reprezentacyjnego (REST) oparte na webowych API jest standardem de facto dla chmur API. Korzystanie z HTTP i JSON sprawia, że jest to łatwe dla programistów, niezależnie od języka programowania, którego używają – PHP, Ruby i Java – do integracji z naszym API bez znajomości lub martwienia się o naszą technologię leżącą poniżej. Jednak budowanie natywnych API w chmurze w dużej skali może stwarzać nieoczekiwane wyzwania infrastrukturalne, takie jak ograniczenia skalowalności DNS, które napotkaliśmy w AWS przy obsłudze dużej ilości ruchu API.

Wybór architektury RESTful był łatwy. Wybór konwencji wersjonowania już nie był taki prosty. Początkowo uniknęliśmy pytania o wersjonowanie, w ogóle nie wersjonując bety. Jednak w ciągu kilku miesięcy beta trafiła w ręce kilku klientów i zaczęliśmy budować naszą usługę w chmurze. Czas na wersjonowanie. Oceniliśmy dwie konwencje wersjonowania. Pierwsza polegała na umieszczeniu wersjonowania bezpośrednio w URI, a druga na użyciu nagłówka Accept. Pierwsza opcja jest bardziej bezpośrednia i mniej skomplikowana, co jest łatwiejsze dla programistów. Ponieważ kochamy programistów, było to logicznym wyborem.

API SparkPost wywodzi się z czasów, gdy byliśmy Message Systems, przed naszymi przygodami w chmurze. W tym czasie byliśmy zajęci końcowymi przygotowaniami do uruchomienia wersji beta Momentum 4. Była to istotna aktualizacja wersji 3.x, naszego wiodącego na rynku lokalnego MTA. Momentum 4 obejmowała całkowicie nowy interfejs użytkownika, analizę w czasie rzeczywistym i co najważniejsze, nowe web API do wstrzykiwania i generowania wiadomości, zarządzania szablonami oraz uzyskiwania metryk emailowych. Naszą wizją była architektura oparta na API – gdzie nawet interfejs użytkownika wchodziłby w interakcję z punktami końcowymi API.

Jedną z najwcześniejszych i najlepszych decyzji, jakie podjęliśmy, było przyjęcie stylu RESTful. Od późnych lat 2000 przenoszenie stanu reprezentacyjnego (REST) oparte na webowych API jest standardem de facto dla chmur API. Korzystanie z HTTP i JSON sprawia, że jest to łatwe dla programistów, niezależnie od języka programowania, którego używają – PHP, Ruby i Java – do integracji z naszym API bez znajomości lub martwienia się o naszą technologię leżącą poniżej. Jednak budowanie natywnych API w chmurze w dużej skali może stwarzać nieoczekiwane wyzwania infrastrukturalne, takie jak ograniczenia skalowalności DNS, które napotkaliśmy w AWS przy obsłudze dużej ilości ruchu API.

Wybór architektury RESTful był łatwy. Wybór konwencji wersjonowania już nie był taki prosty. Początkowo uniknęliśmy pytania o wersjonowanie, w ogóle nie wersjonując bety. Jednak w ciągu kilku miesięcy beta trafiła w ręce kilku klientów i zaczęliśmy budować naszą usługę w chmurze. Czas na wersjonowanie. Oceniliśmy dwie konwencje wersjonowania. Pierwsza polegała na umieszczeniu wersjonowania bezpośrednio w URI, a druga na użyciu nagłówka Accept. Pierwsza opcja jest bardziej bezpośrednia i mniej skomplikowana, co jest łatwiejsze dla programistów. Ponieważ kochamy programistów, było to logicznym wyborem.

API SparkPost wywodzi się z czasów, gdy byliśmy Message Systems, przed naszymi przygodami w chmurze. W tym czasie byliśmy zajęci końcowymi przygotowaniami do uruchomienia wersji beta Momentum 4. Była to istotna aktualizacja wersji 3.x, naszego wiodącego na rynku lokalnego MTA. Momentum 4 obejmowała całkowicie nowy interfejs użytkownika, analizę w czasie rzeczywistym i co najważniejsze, nowe web API do wstrzykiwania i generowania wiadomości, zarządzania szablonami oraz uzyskiwania metryk emailowych. Naszą wizją była architektura oparta na API – gdzie nawet interfejs użytkownika wchodziłby w interakcję z punktami końcowymi API.

Jedną z najwcześniejszych i najlepszych decyzji, jakie podjęliśmy, było przyjęcie stylu RESTful. Od późnych lat 2000 przenoszenie stanu reprezentacyjnego (REST) oparte na webowych API jest standardem de facto dla chmur API. Korzystanie z HTTP i JSON sprawia, że jest to łatwe dla programistów, niezależnie od języka programowania, którego używają – PHP, Ruby i Java – do integracji z naszym API bez znajomości lub martwienia się o naszą technologię leżącą poniżej. Jednak budowanie natywnych API w chmurze w dużej skali może stwarzać nieoczekiwane wyzwania infrastrukturalne, takie jak ograniczenia skalowalności DNS, które napotkaliśmy w AWS przy obsłudze dużej ilości ruchu API.

Wybór architektury RESTful był łatwy. Wybór konwencji wersjonowania już nie był taki prosty. Początkowo uniknęliśmy pytania o wersjonowanie, w ogóle nie wersjonując bety. Jednak w ciągu kilku miesięcy beta trafiła w ręce kilku klientów i zaczęliśmy budować naszą usługę w chmurze. Czas na wersjonowanie. Oceniliśmy dwie konwencje wersjonowania. Pierwsza polegała na umieszczeniu wersjonowania bezpośrednio w URI, a druga na użyciu nagłówka Accept. Pierwsza opcja jest bardziej bezpośrednia i mniej skomplikowana, co jest łatwiejsze dla programistów. Ponieważ kochamy programistów, było to logicznym wyborem.

API Governance

Z wybraną konwencją wersjonowania mieliśmy więcej pytań. Kiedy powinniśmy zwiększyć wersję? Co to jest zmiana łamiąca? Czy przerejestrowalibyśmy całe API, czy tylko niektóre końcówki? W SparkPost mamy wiele zespołów pracujących nad różnymi częściami naszego API. W tych zespołach ludzie pracują nad różnymi końcówkami w różnym czasie. Dlatego bardzo ważne jest, aby nasze API było spójne w używaniu konwencji. To było większe niż wersjonowanie.

Utworzyliśmy grupę zarządzającą, w tym inżynierów reprezentujących każdy zespół, członka zespołu zarządzania produktem i naszego CTO. Ta grupa jest odpowiedzialna za ustanawianie, dokumentowanie i egzekwowanie naszych konwencji API we wszystkich zespołach. Kanał Slack dotyczący zarządzania API także jest pomocny przy żywych debatach na ten temat.

Grupa zarządzająca zidentyfikowała szereg sposobów wprowadzania zmian w API, które są korzystne dla użytkownika i nie stanowią zmiany łamiącej. Obejmuje to:

  • Nowe źródło lub końcówka API

  • Nowy opcjonalny parametr

  • Zmiana w niepublicznej końcówce API

  • Nowy opcjonalny klucz w JSON POST body

  • Nowy klucz zwrócony w JSON response body


Natomiast zmiana łamiąca zawierała wszystko, co mogło złamać integrację użytkownika, takie jak:

  • Nowy wymagany parametr

  • Nowy wymagany klucz w POST bodies

  • Usunięcie istniejącej końcówki

  • Usunięcie istniejącej metody żądania końcówki

  • Zależnie różne wewnętrzne działanie wywołania API – na przykład zmiana domyślnego działania.

The Big 1.0

Podczas gdy dokumentowaliśmy i omawialiśmy te konwencje, doszliśmy również do wniosku, że w interesie wszystkich (w tym naszym!) jest unikanie wprowadzania zmian łamiących w API, ponieważ zarządzanie wieloma wersjami dodaje sporo obciążeń. Zdecydowaliśmy, że przed zobowiązaniem się do „v1” powinniśmy naprawić kilka rzeczy w naszym API.

Wysłanie prostego e-maila wymagało zbyt dużo wysiłku. Aby „utrzymać prostotę rzeczy prostych”, zaktualizowaliśmy treść POST, aby zapewnić, że zarówno proste, jak i złożone przypadki użycia są obsługiwane. Nowy format był również bardziej odporny na przyszłe zmiany. Po drugie, zajęliśmy się problemem z endpointem Metrics. Ten endpoint używał parametru „group_by”, który zmieniał format treści odpowiedzi GET, tak że pierwszy klucz był wartością parametru group_by. To nie wydawało się bardzo RESTful, więc każdy group_by rozdzieliliśmy na oddzielne endpointy. W końcu skontrolowaliśmy każdy endpoint i wprowadziliśmy drobne zmiany tu i tam, aby zapewnić zgodność ze standardami.

Dokumentacja Accurate

Ważne jest posiadanie dokładnej i użytecznej dokumentacji API, aby uniknąć niezamierzonych lub celowych zmian powodujących problemy. Zdecydowaliśmy się użyć prostego podejścia do dokumentacji API, wykorzystując język Markdown zwany API Blueprint i zarządzać naszą dokumentacją na Githubie. Nasza społeczność przyczynia się do ulepszania tych otwartych źródeł dokumentacji.  Prowadzimy również niepubliczny zestaw dokumentacji na Githubie dla wewnętrznych API i punktów końcowych.

Początkowo publikowaliśmy naszą dokumentację w Apiary, świetnym narzędziu do prototypowania i publikowania dokumentacji API. Jednakże, osadzenie Apiary w naszej stronie internetowej nie działa na urządzeniach mobilnych, więc teraz używamy Jekyll do generowania statycznych dokumentów zamiast tego.  Nasza najnowsza dokumentacja API SparkPost ładuje się teraz szybko i działa dobrze na urządzeniach mobilnych, co jest ważne dla programistów, którzy nie zawsze siedzą przy swoim komputerze.

Separating Deployment from Release

Na początku nauczyliśmy się cennej sztuczki oddzielania wdrożenia od wydania. Dzięki temu możemy często wdrażać zmiany, gdy są gotowe, za pomocą ciągłego dostarczania i wdrażania, ale nie zawsze ogłaszamy je publicznie lub dokumentujemy w tym samym czasie. Nie jest niczym niezwykłym, że wdrażamy nowy punkt końcowy API lub ulepszenie istniejącego punktu końcowego API i używamy go w interfejsie użytkownika lub za pomocą narzędzi wewnętrznych zanim go publicznie udokumentujemy i wspieramy. W ten sposób możemy wprowadzać do niego drobne poprawki pod kątem użyteczności lub zgodności ze standardami, nie martwiąc się o wprowadzanie niechcianych zmian powodujących problemy. Gdy jesteśmy zadowoleni ze zmiany, dodajemy ją do naszej dokumentacji publicznej.

Cholera!

Jest tylko uczciwie przyznać, że były czasy, kiedy nie sprostaliśmy naszym ideałom „bez zmian łamiących” i warto się z nich uczyć. W jednym przypadku uznaliśmy, że lepiej byłoby dla użytkowników, gdyby pewna właściwość domyślnie wynosiła true zamiast false. Po wprowadzeniu zmiany otrzymaliśmy od użytkowników kilka skarg, ponieważ zachowanie zmieniło się nieoczekiwanie.  Cofnęliśmy zmianę i dodaliśmy ustawienie na poziomie konta – zdecydowanie bardziej przyjazne podejście dla użytkownika.

Czasami kusi nas wprowadzanie zmian łamiących w wyniku napraw błędów. Jednak zdecydowaliśmy się pozostawić te idiosynkrazje w spokoju, zamiast ryzykować łamanie integracji klientów dla zachowania spójności.

Są rzadkie przypadki, kiedy podjęliśmy poważną decyzję o wprowadzeniu zmiany łamiącej – na przykład wycofanie zasobu lub metody API – w interesie większej społeczności użytkowników i tylko po potwierdzeniu, że ma to niewielki lub żaden wpływ na użytkowników. Na przykład celowo podjęliśmy decyzję o zmianie zachowania odpowiedzi API Suppression, ale dopiero po dokładnym rozważeniu korzyści i wpływu na społeczność oraz dokładnym komunikowaniu zmiany naszym użytkownikom. Jednak nigdy nie wprowadzilibyśmy zmiany, która ma nawet najmniejsze prawdopodobieństwo bezpośredniego wpływu na wysyłanie emaila produkcyjnego użytkownika.

Połączmy Cię z ekspertem Bird.
Zobacz pełną moc Bird w 30 minut.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

Company

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.

Połączmy Cię z ekspertem Bird.
Zobacz pełną moc Bird w 30 minut.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

Company

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.

Połączmy Cię z ekspertem Bird.
Zobacz pełną moc Bird w 30 minut.

Przesyłając, zgadzasz się, że Bird może kontaktować się z Tobą w sprawie naszych produktów i usług.

Możesz zrezygnować z subskrypcji w dowolnym momencie. Zobacz Privacy Statement firmy Bird, aby uzyskać szczegóły dotyczące przetwarzania danych.

R

Reach

G

Grow

M

Manage

A

Automate

Company

Biuletyn

Bądź na bieżąco z Bird dzięki cotygodniowym aktualizacjom do Twojej skrzynki odbiorczej.