GraphQL

Język zapytań do API, który pozwala klientowi pobrać dokładnie te dane, których potrzebuje, jednym żądaniem. Alternatywa dla REST opracowana przez Facebooka.

GraphQL (Graph Query Language) to język zapytań do API, w którym to klient decyduje, jakie dane chce dostać, a serwer odsyła dokładnie tyle, ile poproszono — ani bajta więcej. Zamiast wielu adresów (jak w REST) masz zwykle jeden endpoint, najczęściej /graphql, do którego wysyłasz zapytanie opisujące potrzebny kształt odpowiedzi. GraphQL powstał w Facebooku w 2012 r. na potrzeby aplikacji mobilnej, a publicznie udostępniono go w 2015 r. Dziś rozwija go GraphQL Foundation (pod skrzydłami Linux Foundation), więc to już nie jest „zabawka jednej firmy”.

Jak to działa

Sercem GraphQL jest schema — kontrakt opisujący, jakie typy i pola istnieją oraz jakie operacje są dozwolone. Operacje są trzy: query (czytanie), mutation (zapis) i subscription (dane w czasie rzeczywistym). Kiedy wyślesz zapytanie, serwer uruchamia tzw. resolvery — małe funkcje, które wiedzą, skąd wziąć wartość każdego pola (z bazy, z innego API, z cache).

Największa zaleta to koniec z over-fetchingiem (dostajesz pół encyklopedii, gdy chcesz jedno imię) i under-fetchingiem (musisz odpytać pięć endpointów, żeby złożyć jeden ekran). Pytasz raz, o konkretne pola, i tyle dostajesz.

Przykład z praktyki

Załóżmy, że budujesz profil użytkownika i potrzebujesz tylko nazwy oraz tytułów jego postów. Zapytanie wygląda tak:

query { user(id: "42") { name posts { title } } }

W odpowiedzi dostaniesz JSON o identycznej strukturze — data.user.name i lista posts z samymi title. Po stronie frontendu najczęściej spotkasz Apollo Client albo urql, a do zabawy i debugowania świetnie sprawdza się GraphiQL lub Apollo Sandbox — interaktywne IDE w przeglądarce, gdzie podpowiadanie pól bierze się wprost ze schemy.

Częste błędy i mity

Mit pierwszy: „GraphQL zastąpi REST”. Nie zawsze — do prostego API REST bywa wygodniejszy i łatwiej go cache’ować. Mit drugi: „skoro to jeden endpoint, to bezpieczniej”. Wręcz przeciwnie, klient może ułożyć kosztowne, głęboko zagnieżdżone zapytanie i położyć ci serwer, więc warto wdrożyć limity głębokości i query complexity. Uważaj też na problem N+1 w resolverach — bez narzędzia typu DataLoader jedno zapytanie potrafi wystrzelić setki zapytań do bazy. I pamiętaj: cache po stronie HTTP nie działa „za darmo” jak w REST, bo wszystko leci jednym POST-em.

Pojęcia powiązane

REST, gRPC, JSON, schema i SDL (Schema Definition Language), resolver, Apollo, query, mutation, subscription, endpoint, over-fetching.