Skip to content
Language:hu Author:Laborci Gergely
api

GraphQL: séma, resolver és mezőigény

Célok

A lecke végére el tudod magyarázni a GraphQL alapgondolatát, a resolver és az N+1 probléma szerepét, a lekérdezési költség kérdését, és a hét szempont szerint jellemezni tudod.

Miért kell?

Ha sok, eltérő igényű kliens ugyanazokat az adatokat kéri, a rögzített válaszformájú végpontok vagy túl sokat adnak vissza, vagy túl sok hívást igényelnek (6.3). A GraphQL azt a problémát kezeli, hogy a kliens maga válassza meg, milyen mezőket kér.

Mi a GraphQL?

A GraphQL a graphql.org szerint „rugalmas, verziómentes API-kat” tesz lehetővé erős típusrendszerrel. A séma típusokkal írja le a kliens számára elérhető adatokat és műveleteket; a kliens lekérdezésben (query) pontosan megadja a szükséges mezőket. A szerver resolverekkel állítja elő a mezők értékét, akár több adatforrásból vagy szolgáltatásból.

A séma nem az adatbázis automatikus tükre: a fogyasztónak szánt fogalmakat írja le. Egy típus mezői három különböző adatgazdától is származhatnak. A kért mezők megadása csökkentheti a túl nagy reprezentációkat, de nem garantálja önmagában az olcsó lekérdezést.

A műveletfajták: a query olvas, a mutation állapotot változtat, a subscription időben több eredményt ad. A specifikáció szerint a subscription műveletnek pontosan egy gyökérmezője van; a specifikáció a hordozó protokollt nem rögzíti (csak példaként említi a HTTP-t), ezért a konkrét szállítást, a hitelesítést és az újracsatlakozást a használt megoldás szerződése adja meg.

Egy végpont és a státuszkód

A graphql.org szerint a GraphQL-szerver jellemzően egyetlen URL-en (általában /graphql) fogad minden kérést. A POST kötelezően támogatott lekérdezésre és mutationre, a GET csak lekérdezésre használható. A válasz egyszerre tartalmazhat data-t és errors-t. A specifikáció szerint ha az errors jelen van, és a data nem hiányzik, a hibák mezőszintű hibák lehetnek; a graphql.org szerint ha a data nem null, a válasz 2xx lehet akkor is, ha hibák vannak, mert a HTTP-nek nincs „részleges siker” státusza. A kliensnek ezért a részleges eredményt is értelmeznie kell.

Resolverek és N+1

Egy lista lekérdezése húsz elemet adhat; ha minden elem egy mezőjéhez külön adatforrás-kérés tartozik, az eredmény egy kezdeti és húsz további kérés. Ez az N+1 probléma. A graphql.org megoldása a batching: a rövid idő alatt gyűlt kéréseket egyetlen kéréssé vonják össze (például DataLoader-szerű eszközzel).

flowchart LR
  C["Kliens lekérdezése"] --> G["GraphQL végpont"]
  G --> R["Resolverek"]
  R --> B["Batch"]
  B --> S1["Adatforrás 1"]
  B --> S2["Adatforrás 2"]

Költség és gyorsítótár

Egy típus szerint érvényes lekérdezés sok adatforrás-hívást vagy nagy adathalmazt indíthat. A graphql.org szerint a komplex műveletek túlterhelhetik az adatforrásokat, ezért a lapozás, a mélység és szélesség korlátozása és a lekérdezés-komplexitás elemzése véd. A GraphQL gyorsítótárazható, mint bármely paraméterezett API; a GET lekérdezések gyorsítótárazhatók, a nagy lekérdezésekhez „persisted query” (hash küldése) használható.

Jellemzők

Szempont GraphQL
Irány Kérés–válasz; subscription esetén a szerver felől is
Kezdeményező A kliens
Kapcsolat tartóssága Query/mutation: kérésenként; subscription: a használt transporttól függ
Késleltetés Egy kérés–válasz út, de a szerveren fan-out
Terhelés A kérés összetettségétől függ; korlátozni kell
Hibatűrés Részleges eredmény (data + errors)
Mikor jó? Sokféle kliens, eltérő mezőigény, összetett olvasási felület
Mikor nem? Egyszerű belső parancsinterfész; erősen gyorsítótárazott erőforrás-olvasás

Gyakori tévhitek

Állítás Pontosítás
„A GraphQL mindig gyorsabb.” Kevesebb kliens-kérés, de a szerveren fan-out lehet.
„A GraphQL kiváltja a REST-et.” Más kompromisszumok; több stílus is együtt élhet.
„A subscription mindig WebSocket.” A specifikáció nem rögzíti a hordozó protokollt.
„A HTTP 200 azt jelenti, hogy nincs hiba.” A válasz errors-t is tartalmazhat.

Röviden

  • A GraphQL séma és mezőigény alapú: a kliens megmondja, mit kér.
  • A resolverek mögött fan-out és N+1 lehet; batching csökkenti.
  • A lekérdezés költségét korlátozni kell.
  • A válasz részleges lehet; a HTTP-státusz önmagában nem mond el mindent.

Ellenőrző kérdések

  1. Mi az N+1 probléma, és mi csökkenti?
  2. Miért kell korlátozni a lekérdezés mélységét és komplexitását?
  3. Mit jelent az, hogy a válasz tartalmazhat data-t és errors-t egyszerre?

Források

Prerequisites (2)

  • szinkron és aszinkron kommunikáció
  • kommunikációs szerződés

Teaches (1)

  • GraphQL