W poszykiwaniu idealnego RESTowego API

Na potrzeby aplikacji mobilnych, czy aplikacji JavaScriptowych pisanych w Emberze, czy Angularze musimy wystawiać RESTowe API, by zapewnić prosty sposób na integrację tychże aplikacji z naszym backendem, bazą danych itd. Jak więc powinno wyglądać dobre API? Jakie narzędzia będą najlepsze? Czym należy się kierować tworząc takie API? Spróbujmy zagłębić się w ten temat.

Wymagania dobrego API

Zacznijmy może od testów i bezpieczeństwa. Dobre API powinno być łatwo testowalne, szczególnie wszystkie aspekty uprawnień i dostępu do danych. Łatwo w API wystawić coś więcej niż potrzeba. Pisząc testy fajnie by było gdyby dało się testować zasób API bez konieczności wykonywania żądań HTTP i operowania na JSONie - zasób zwraca słownik i np. porównujemy go z oczekiwanym słownikiem. Dzięki temu test jest krótki, szybki i przejrzysty.

Wracając do autoryzacji - dobrze by było, gdyby framework do wystawiania API obsługiwał praktyczne mechanizmy autoryzacji. Ciasteczko z sesją nie jest najlepsze bo third party cookies mają swoje ograniczenia i nie zawsze można je ustawić (co dotyczy np. aplikacji Facebookowych z JavaScriptem komunikującym się z backendem). Tokeny, czy autoryzacja HTTP przesyłana w nagłówku żądania nie ma już ograniczeń takich ciasteczek. Sam zasób API nie musi wiedzieć czy dany użytkownik/żądanie ma wymagane uprawnienia. Jeżeli aplikacja jest duża i zmodularyzowana, to jedno API mogłoby odpytać się drugiego czy zrealizować dane żądanie (a mogą to być dwie różne aplikacje niepowiązane ze sobą).

Mając już dużą i zmodularyzowaną listę zasobów API fajnie by było, gdyby mieć najprostsze i najlepsze narzędzie do zrealizowania danego zasobu. Jeżeli np. potrzebujemy wystawić na API szereg raportów ze zagregowanych danych zwróconych przez SQLkę to np. Django ze swoim ORMem potrzebne nie będzie. W takim przypadku lepsze mogło by być coś lżejszego bez długiego ogona zależności, albo framework specjalizujący się w wystawianiu API w oparciu o bazę danych, zapytania SQL.

PubSub też czasami jest bardzo pożądany. Gotowa platforma narzędziowa z obsługą PubSuba, pushowania danych do klientów znacząco oszczędzałaby wtedy nasz czas i pozwalała tworzyć bardziej niezawodne aplikacje.

Na sam koniec warto wspomnieć o wersjonowaniu API - wprowadzając zmiany w zasobach czasami okażą się one wstecznie niezgodne. W takich przypadkach przydaje się wersjonowanie API. Dobrze by było, by przy tym wersjonowaniu nie duplikować kodu, robić to w dość przejrzysty sposób.

Co Python oferuje dobrego?

Zacznijmy może od Django. Swego czasu popularny był Tastypie, a teraz prym wiedzie raczej Django Rest Framework. Skupmy się więc na DRF. Oparty o widoki klasowe, czy zestaw miksinów pozwala tworzyć zasoby w elastyczny sposób. Jeżeli api ma zwracać tylko listę, albo obsługiwać tylko żądania POST do tworzenia obiektów to nie ma z tym problemów. Testowanie np. z wykorzystaniem APITestCase pozwala wymuszać autoryzację użytkownika, a klient zwraca odpowiedź w postaci słownika. Ale w wielu przypadkach test można uprościć testując bezpośrednio na widoku z wykorzystaniem RequestFactory. Wystarczy wywołać określoną metodę klasy (np. retrieve) i gotowe. Obsługiwana jest też autoryzacja tokenem, czy za pomocą OAuth. W przypadku tokena brakuje paru dodatków (jak np. regenerowanie klucz, gdy użytkownik zmienia swoje hasło), ale działa prosto i skutecznie. DRF sprawdzi się idealnie, gdy chcemy wystawiać API dla modeli Django. Może nie być najlepszym wyborem dla API niepowiązanego z modelami Django (szczególnie, gdy ma być ich wiele).

fullstackpython listuje też inne pythonowe narzędzia do wystawiania API. Falcon Framework to przykład minimalistycznego narzędzia, który nie zależy od żadnego frameworka webowego. To potencjalny kandydat do wystawiania nietypowego API, które nie mapuje się na model ORMa, czy tabelę w bazie danych. Nie używałem go jeszcze, więc trudno mi się wypowiadać o testowalności Falcona, ale co nieco jest w dokumentacji (zawsze mogło by być więcej). Restless to drugi minimalistyczny framework tego typu.

Sandman to framework powiązany z Flaskiem, choć sam mapuje tabele w bazie danych na zasoby API. Oczywiście ma szereg opcji konfiguracji jego działania. To potencjalny kandydat na np. wewnętrzne API, z jakiego korzystać mogą niektóre inne zasoby. Oferuje też np. autoryzację tokenem więc da się dość dokładnie kontrolować dostęp do danych zasobów.

A co w przypadku pubSuba, websoketów? Tutaj jeszcze nie miałem z niczym do czynienia, więc trudno mi coś polecić, wybrać spośród dostępnych rozwiązań. Na leggetter.co.uk wymieniono szereg usług jak i narzędzi do hostowania samemu, które można do tego wykorzystać. Używaliście już coś, co można polecić?

Na zakończenie

Jak na razie zasoby API używałem głownie do budowania aplikacji emberowych. W jednym projekcie sklep wystawiał API na potrzeby aplikacji mobilnych. We wcześniejszych aplikacjach API wystawiał Tastypie, który da się nagiąć by wystawiał mocno zmodyfikowane dane, ale czasami walidacja, czy testowanie bywało niezbyt oczywiste, czy problematyczne. Dlatego w nowszych, bieżących aplikacjach używam DRF, który problemów nie stwarza. Na potrzeby obecnej modularnej, zdokeryzowanej aplikacji poszukuje też narzędzi najlepszych dla danego zadania i tam pojawia się właśnie miejsce na inne narzędzia wystawiające API. Docker ułatwia takie właśnie rozbicie na mniejsze komponenty realizujące swoje zadania w najlepszy sposób, bez problemu z zależnościami i bibliotekami innych komponentów, głównej aplikacji.

A wy z czego korzystacie, co możecie polecić?

RkBlog

Programowanie Sieciowe, 22 February 2015

Comment article
Comment article RkBlog main page Search RSS Contact