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.