W 2015 roku Facebook udostępnił kod źródłowy do nowego standardu API, które stanowi alternatywą do tradycyjnego RESTa. Zaprezentowane rozwiązanie w żadnym wypadku nie było eksperymentem, ponieważ aplikacje mobilne Facebooka korzystały z niego od 2012 roku. Mowa tutaj o niczym innym jak GraphQL.
GraphQL krótko po publikacji zyskał dużą popularność, okazało się, że na takie rozwiązanie istniało zapotrzebowanie na rynku bo kilka dużych firm kombinowało już wcześniej z podobnymi implementacjami. Dla przykładu Coursera porzuciła plany na rozwój swoich pomysłów i postanowiła wdrożyć GraphQL u siebie, a najnowsza wersja API publicznego GitHuba została w całości oparta na GraphQL. Z pewnością dużą popularność temu rozwiązaniu przynosi fakt, że jest niezależna od technologii i można znaleźć gotowe biblioteki implementujące ten standard w większości popularnych języków programowania.
Czym jest GraphQL
W celu wyjaśnienia głównych założeń GraphQL najlepiej posłużyć się przykładem i porównać działanie z RESTem, który według Facebooka jest mniej wydajnym rozwiązaniem co w rezultacie skłoniło ich do opracowania nowego standardu.
Załóżmy, że pracujemy nad API, z którego będzie korzystała aplikacja webowa i mobilna. API wystawia informacje o książkach i ich autorach. Mamy do przygotowania podstronę wyświetlającą autora i jego wszystkie książki.
-
Wersja webowa powinna wyświetlać:
- Imię i nazwisko autora i jego krótkie bio
- Tytuły książek wraz z krótkimi opisami
-
W aplikacji mobilnej dane powinny być skrócone:
- Imię i nazwisko autora
- Tytuły książek
Jeśli tworzone API jest oparte o standard REST wykonane zostaną dwa wywołania GET /authors/{id}
oraz GET /authors/{id}/books
, które zwrócą pełne informacje.
GET /authors/{id} { "id": "32211" "name": "Remigiusz Mróz", "bio": "..." "birthday": "Thu, 15 Jan 1987" "sex": "male" }
GET /authors/{id}/books { "books": [{ "id": "98754", "title": "Wotum nieufoności", "shortDescription": "...", "description": "", "pages": "624", "isbn": "...", "releaseDate": "Wed, 11 Jan 2017" }, ... ] }
Szybko można zauważyć, że API zwraca więcej danych niż jest to potrzebne do wyświetlenia w obu przypadkach. Aplikacja mobilna przy listowaniu książek potrzebuje tylko tytułów, a dostaje komplet informacji (krótki i długi opis, liczba stron, data wydania itp.). W komunikacji mobilnej ważna jest oszczędność, a w tym wypadku ewidentnie pobierana jest nadmiarowa ilość danych.
Oczywiście istnieje mnóstwo podejść rozwiązujących ten problem. Można tworzyć różne endpointy, które w odpowiednim momencie zwrócą interesujące nas dane lub zaimplementować API w taki sposób aby podczas wywołania istniała możliwość wybrania pól, np. GET /authors/{id}/books?only=title
. Problemem może okazać się rzeczywistość – jak wiadomo wymagania w projektach ciągle się zmieniają i po czasie takie rozwiązania mogą okazać się bardzo trudne w utrzymaniu.
I w tym miejscu do gry wkracza GraphQL…
Elastyczność
Serwer oparty o GraphQL w odróżnieniu od RESTa wystawia tylko jeden endpoint, który oczekuje odpowiednio sformułowanego zapytania. To klient wybiera jakie dane chce otrzymać w odpowiedzi, która przychodzi w formacie JSON. Dla powyższego przykładu z listą książek można zbudować odpowiednie zapytania dla każdego z klientów (aplikacja webowa i mobilna).
Aplikacja webowa wysyłając poniższe zapytanie:
query { Author(id: "32211") { name bio books { title shortDescription } } }
Może oczekiwać podobnej odpowiedzi:
{ "data": { "Author": { "name": "Remigiusz Mróz", "bio": "...", "books": [{ "title": "Wotum nieufoności", "shortDescription": "..." }, ...] } } }
Z kolei aplikacja mobilna odpytując serwer z odpowiednim zapytaniem:
query { Author(id: "32211") { name books { title } } }
Otrzyma wynik:
{ "data": { "Author": { "name": "Remigiusz Mróz", "books": [{ "title": "Wotum nieufoności" }, ...] } } }
Jak widać jednym zapytaniem pobieramy wszystkie interesujące nas informacje bez nadmiarowych danych. I to jest główne założenie GraphQL – elastyczność. Nie trzeba dostosowywać endpointów pod konkretne widoki. Raz zdefiniowany schemat wykorzystywany jest przez wszystkich klientów dokładnie w taki sposób jak tego potrzebują.
Mniejsza ilość zapytań
Powyżej można było przeczytać, że GraphQL wystawia tylko jeden endpoint co również jest istotne. W tradycyjnym podejściu RESTowym często wykonywanych jest dużo zapytań aby wyświetlić informacje w jednym widoku aplikacji – nie jest to efektywne w kontekście aplikacji mobilnych bo duża ilość zapytań spowalnia działanie aplikacji i powoduje większy transfer danych przesyłanych przez Internet. Dzięki rozwiązaniom zaprezentowanym przez inżynierów Facebooka wymagana komunikacja między klientem, a serwerem jest zoptymalizowana.
Silne typowanie
Bardzo ważnym elementem GraphQL jest silne typowanie definiowanego API co jest kolejną różnicą w stosunku do RESTa, przy którym nigdy nie wiadomo czego można oczekiwać w odpowiedzi. Schemat wszystkich typów definiowany jest przy pomocy GraphQL Schema Definition Language (SDL) i dzięki niemu określany jest jasny kontrakt między backendem i frontendem.
Dokumentacja
Aby utrzymać dobrą i aktualną dokumentację API opartego o REST potrzebna jest duża dyscyplina i najczęściej wykorzystanie dodatkowych narzędzi, które pomagają przy generowaniu takiej dokumentacji. W GraphQL mając do czynienia z silnym typowaniem schematu otrzymujemy dokumentację jak na tacy. Do eksplorowania API opartego na GraphQL przygotowano narzędzie GraphiQL, które dostępne już również w formie wtyczki ChromeiQL do przeglądarki chrome.
GraphQL to język zapytań
Istotną sprawą jest fakt, że GraphQL nie jest rozwiązaniem stworzonym pod konkretną technologię – GraphQL to język zapytań posiadający konkretne zasady i wzorce, które mogą być implementowane dla różnych środowisk. Już teraz istnieje sporo bibliotek, które go wspierają w różnych technologiach, takich jak: C#/.NET, PHP, JavaScript, Java, Python, Ruby i wiele innych.
Podsumowanie
Na koniec warto zastanowić się czy powinniśmy porzucić implementacje naszych API opartych na zasadach zgodnych z RESTem i przenieść się na GraphQL skoro daje tyle możliwości? Czy to koniec ery API opartych o RESTa i teraz każdy szanujący się developer powinien myśleć o migracji na GraphQL? Brzmi obiecująco, prawda? No dobra, ale najpierw warto odpowiedzieć sobie na pytanie: czy kiedykolwiek miałem jakieś problemy wspomniane wcześniej z RESTowym API, nad którym pracuję?
Nowa technologia na horyzoncie nie oznacza, że trzeba porzucać wszystko i od razu ją adaptować. Warto zastanowić się czy faktycznie dane rozwiązanie wprowadziłoby wartość dodaną i przyniosło w przyszłości wymierne korzyści oprócz dobrego samopoczucia developerów, że skorzystali z nowej technologii.
Moim zdaniem GraphQL idealnie wpasowuje się w kilka sytuacji:
- kiedy oszczędność jest ważna podczas transferu danych, np. wtedy gdy z naszego API korzystają aplikacje mobilne – czyli to co skłoniło programistów z Facebooka do wymyślenia nowego standardu
- kiedy nasze API jest ogromne i oferuje wiele możliwości dla niezliczonej ilości klientów – tutaj świetnym przykładem może być właśnie GitHub, który udostępnia pełno informacji na temat commitów, repozytoriów itp., ale bardzo często klienci używają tylko kilku pól.
- Kiedy zależy nam na jasnej i czytelnej strukturze API – to również bardzo dobrze wpisuje się w różnego typu API publiczne.
Podsumowując – nowe rozwiązanie zaproponowane przez Facebooka dużo bardziej pasuje pod API publiczne z którego korzystać może tysiące różnych klientów gdzie każdy z nich może interpretować dane wyjściowe w różny sposób i będzie potrzebował innego zestawu informacji. Jeśli implementujemy wewnętrzny serwis, który wykorzystywany jest jedynie przez jedną aplikację webową pozostałbym przy zwykłym, tradycyjnym i sprawdzonym RESTowym API.
Super. Już nie mogę się doczekać implementacji w asp core.
http://asp.net-hacker.rocks/2017/05/29/graphql-and-aspnetcore.html 🙂
[…] artykuł na temat GraphQL możecie przeczytać tutaj: http://devenv.pl/graphql-podstawy/ Podam parę ciekawostek […]