Wstęp do GraphQL

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.

GraphiQL

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.

Programista skupiony głównie wokół technologii webowych, ale nie przywiązujący się do konkretnych języków i narzędzi. Skoncentrowany na ciągłym rozwoju, zwolennik ruchu Software Crafmanship. Na codzień pracując w DAZN ma okazję rozwijać interesujący projekt do streamingu wydarzeń sportowych. Prywatnie fan sportu, a szczególnie piłki nożnej. Po godzinach próbuje również swoich sił w piwowarstwie domowym.
PODZIEL SIĘ

3 KOMENTARZE

Comments are closed.