Czy zdarzyło Wam się kiedyś, że zwracaliście w API dane, które nie zawsze były wykorzystywane, a jedynie przydawały się w konkretnych sytuacjach? Na przykład: potrzebowaliście listy przedmiotów tylko po nazwie, a API zwraca dodatkowo kategorię oraz powiązane przedmioty, które nie są potrzebne w danej sytuacji, jednak inne miejsca w systemie z nich korzystają (over-fetching)? Albo wręcz odwrotnie – mieliście zbyt mało danych? Przez co, celem wyświetlenia listy produktów, musieliście wykonywać kolejne requesty, by pobrać informacje o powiązanych produktach (under-fetching)?
Możemy w takiej sytuacji tworzyć dedykowane endpointy lub też parametryzować (w zależności od interesujących nas informacji), ale zarządzanie takim API może stawać się z czasem coraz bardziej uciążliwe i nieefektywne.
GraphQL
Na szczęście z pomocą przychodzi nam opracowany przez firmę Facebook silnie typowany język zapytań GraphQL. Intuicyjna składnia GraphQL pozwala na pobieranie danych (Query), ich edycję i wstawianie (Mutation) oraz obserwowanie zmian w czasie rzeczywistym (Subscription). Język ten pozwala dokładnie określić jakie dane nas interesują na wyjściu, jak głęboko chcemy pobierać obiekty powiązane ze sobą oraz co dokładnie chcemy modyfikować.
Przykłady
Tworzymy typ “Product”, który posiada nazwę, powiązane produkty oraz kategorię. Jest on wykorzystany w domyślnym typie “Query” – wymaganym do działania. Tak stworzony schemat pozwala nam na pobranie wszystkich produktów i produktów powiązanych, wraz z kategoriami.
type Query { allProducts: [Product]! } type Product { id: ID name: String related: [Product]! categories: [Category]! } type Category { id: ID name: String }
Spróbujmy pobrać listę produktów (id, name), kategorie (name), oraz powiązane przedmioty (id, name) wraz z przypisanymi im kategoriami (name).
{ allProducts { id name categories { name } related { id name categories { name } } } }
Jeśli potrzebowalibyśmy dodatkowych zagnieżdżeń, możemy je po prostu dopisać:
[...] related { id name categories { name } related { id name categories { name } } } [...]
Wysyłając nasze pierwsze query do serwera, możemy otrzymać przykładowe dane:
{ "allProducts": [ { "id": 153, "name": "kolczyki", "categories": [ { "name": "Biżuteria" } ], "related": [ { "id": 156, "name": "pierścionek złoty", "categories": [ { "name": "Biżuteria" }, { "name": "Złoto" } ] } ] }, [...] ] }
Jak widać, otrzymaliśmy dokładnie to, o co prosiliśmy.
Przedstawiony został tu uproszczony przykład tylko dla operacji Query, więcej przykładów można znaleźć na oficjalnej stronie https://graphql.org/learn/.
Autorem tekstu jest Maksym Kuras.