Co je GraphQL a proč vznikl
GraphQL je dotazovací a manipulační jazyk pro API a zároveň runtime pro provádění dotazů nad datovým grafem. Vznikl ve Facebooku (2012, otevřen v roce 2015) jako reakce na limity RESTu u složitých klientských aplikací: příliš mnoho „koleček“ mezi klientem a serverem, overfetching (stahujeme více dat než potřebujeme) a underfetching (nutnost vícero volání pro sestavení jedné obrazovky). GraphQL umožňuje klientovi přesně deklarovat, která pole potřebuje, v jednom požadavku napříč více zdroji, nad jednotným schématem typů.
Základní stavební prvky: schéma, typy a resolver
- Schéma (SDL – Schema Definition Language) definuje typy, pole a jejich vztahy. Je to kontrakt mezi klientem a serverem.
- Kořenové typy:
Query(čtení),Mutation(změny) aSubscription(stream událostí). - Resolver je funkce, která pro dané pole vrací data. Řeší napojení na DB, služby, cache apod.
Ukázka schématu (SDL) a základních dotazů
type User { id: ID! name: String! email: String! posts(first: Int, after: String): PostConnection! } type Post { id: ID! title: String! body: String! author: User! createdAt: String! } type PostEdge { node: Post! cursor: String! } type PageInfo { endCursor: String, hasNextPage: Boolean! } type PostConnection { edges: [PostEdge!]! pageInfo: PageInfo! } type Query { me: User post(id: ID!): Post users(limit: Int = 10): [User!]! } type Mutation { createPost(title: String!, body: String!): Post! } type Subscription { postCreated: Post! }
# Dotaz s přesnými poli query { me { id name posts(first: 10) { edges { node { id title } } pageInfo { hasNextPage } } } }
# Mutace s návratovou strukturou mutation { createPost(title: "GraphQL", body: "Hello") { id title author { name } } }
GraphQL vs. REST: srovnání paradigmat
- Granularita: REST vrací pevně dané reprezentace; GraphQL vrací přesně to, co si klient nadefinuje.
- Navigace: REST používá URL a zdroje; GraphQL naviguje grafem přes pole a vztahy.
- Verzování: REST často verzování v URL (
/v1,/v2), GraphQL preferuje evoluci schématu (deprecations, non-breaking changes). - Chyby: REST = stavové kódy HTTP; GraphQL = pole
errorsv JSON odpovědi + (typicky)200 OKna transportní vrstvě.
Silná typová kontrola a introspekce
Schéma je silně typované. Klienti využijí introspekci ke zjištění dostupných typů, polí a argumentů; díky tomu vznikají nástroje jako GraphiQL, GraphQL Playground, generátory SDK (TypeScript/Kotlin/Swift) a validace dotazů v CI.
Architektura serveru: resolvery, kontext, datové zdroje
- Resolvery: mapují pole na implementaci (DB dotaz, volání REST/gRPC, cache). Každé pole může mít svůj resolver.
- Kontext: požadavkový kontejner (uživatel, tokeny, loaders, trace ID).
- DataSources: opakovaně použitelné konektory s vestavěným cachováním a retry (např. Apollo DataSource).
Výkonnost: N+1 problém a jeho mitigace
Vnořené resolvery mohou vést k N+1 dotazům (např. pro 100 příspěvků 100 dotazů na autora). Zmírnění:
- Batching a caching přes DataLoader (seskupí dotazy by ID do jedné DB operace).
- Projection/select optimalizace: načítat pouze požadovaná pole.
- Joins/CTE na DB vrstvě nebo předpočítané pohledy.
Stránkování a filtrování: offset vs. cursory
GraphQL nenařizuje konkrétní paging, ale v praxi se prosadil cursor-based model (Relay specifikace: edges, node, pageInfo). Je stabilnější vůči vkládání/mazání řádků než offset/limit a snižuje riziko ztráty/duplicit.
Subscriptions a realtime
Subscription umožňuje streamovat události klientovi (WebSocket, SSE, MQTT). Typické scénáře: chat, notifikace, live metriky. Server drží kanál a publikuje payload dle schématu; škálování vyžaduje broker (Redis, Kafka) a sticky sessions či pub/sub vrstvu.
Směrování a federace schémat
- Schema Stitching: spojování více schémat na gateway.
- Apollo Federation: deklarativní federace s
@key,@provides,@requiresa subgraph službami; gateway resolvuje referenční entity napříč doménami. - Remote joins a grafové routery: směrují části dotazu do mikroservis, agregují odpovědi.
Bezpečnost: autorizace, limity a ochrana proti zneužití
- Autentizace v kontextu (JWT, mTLS, OAuth 2.0).
- Autorizace na úrovni polí (directive
@auth), policy enforcement ve resolveru nebo gateway. - Depth/complexity limit: omezení hloubky, počtu uzlů a šířky dotazu, aby se zabránilo drahým dotazům.
- Persisted queries: klient posílá hash předem zaregistrovaného dotazu ⇒ kratší payload, nižší riziko injekce.
- Rate limiting, throttling, cost analysis per pole (váhy dle nákladnosti).
Cache a výkon: vrstvy a strategie
- Client cache: normalizace entit (Apollo Client, Relay); write policies, cache redirects, optimistic UI.
- Server cache: per-field/per-resolver cache, response caching (u persisted queries), mikrocache (ms–s) na gateway.
- CDN: těžší kvůli POST a variabilitě dotazů; pomáhá persisted GET + cache key podle hash dotazu a proměnných.
Vývojové workflow: kontrakty, typová generace a CI
- SDL-first vs. code-first (Nexus, TypeGraphQL). Důležité je, aby byl schématový kontrakt zdrojem pravdy.
- Generování typů (TypeScript/Swift/Kotlin) z introspection a z dotazů – snižuje runtime chyby.
- Linting a schema validation v CI (breaking changes detekce, deprecation audit).
Evoluce a správa schématu (schema governance)
- Non-breaking změny: přidávat pole s defaulty, označovat staré
@deprecated. - Breaking změny plánovat s migračním oknem a telemetrií (kdo ještě čte stará pole?).
- Changelog, contract tests pro klíčové klienty, schema registry (Apollo Studio, GraphQL Hive).
Defer/Stream, živé dotazy a file upload
- @defer a @stream: postupné doručování částí odpovědi (lepší time-to-first-byte u velkých grafů).
- Live queries: klient udržuje dotaz „živý“ a server posílá změny (alternativa k subscriptions u některých gateway).
- Nahrávání souborů: multipart request (specifikace graphql-multipart-request-spec), pole
Uploada perzistence v objektovém úložišti.
Chyby a jejich modelování
- GraphQL odpověď má
dataaerrors; částečný úspěch je možný (část polí selže). - Pro doménové chyby modelujte výsledkové typy (union
Success | Error) nebo polymorfní payload s chybovým polem. - Přidávejte
extensionspro kódy, trace ID, tipy pro klienta.
Monitorování, tracing a observabilita
- Tracing per field (Apollo, OpenTelemetry): které resolvery jsou nejdražší? latence, počet volání, cache hit ratio.
- Field-level metrics, error rates, p95/p99 latence; korelace s backend službami.
- Query safelisting a audit: které dotazy běží, kdo je volá, s jakými proměnnými.
Integrace s existujícím ekosystémem
- Backend: Node.js (Apollo Server, Helix), JVM (GraphQL Java), .NET (Hot Chocolate), Go (gqlgen), Python (Strawberry, Graphene).
- Frontend: Apollo Client, Relay, URQL; generátory SDK (graphql-code-generator).
- Hybridní přístup: GraphQL gateway před REST/gRPC mikroslužbami, postupná adopce bez přepisování backendu.
Bezpečné a škálovatelné nasazení: osvědčené postupy
- Zapněte depth/complexity limit, persisted queries a timeouty resolverů.
- Udržujte idempotentní a deterministické resolvery; používejte retry s jitterem.
- Pro vertikální škálování navyšte CPU/RAM; pro horizontální použijte gateway + read-through cache a pub/sub pro subscriptions.
Typické antipatterny
- Jeden mega-dotaz vracející „všechno“ – ztrácí granularitu a kontrolu nad náklady; omezte šířku a hloubku.
- Resolver per řádek DB bez batchingu – vede k N+1; použijte DataLoader.
- Absence autorizace na poli – únik citlivých polí i když je UI nezobrazuje.
- Skryté breaking changes – mazání/renaming bez deprecations a telemetrie.
Praktický mini–design: feed příspěvků
# Schéma type FeedItem { id: ID! title: String! snippet: String! author: User! createdAt: String! } type Query { feed(first: Int, after: String): FeedConnection! }
# Dotaz (klient si volí pole) query Feed($first: Int = 20) { feed(first: $first) { edges { node { id title author { id name } createdAt } cursor } pageInfo { hasNextPage endCursor } } }
# Poznámky k implementaci: 1) resolver feed načítá minimum sloupců; 2) author je batchován dle author_id; 3) přidejte complexity weight pro pole feed.
Check-list pro adopci GraphQL v organizaci
- Use-case fit: více klientů (web, mobil), složité obrazovky, agregace z více zdrojů, potřeba rychlé iterace.
- Governance: vlastník schématu, review a deprecations proces, telemetrie dotazů.
- Bezpečnost: autentizace v kontextu, autorizace na poli, rate/complexity limity, persisted queries.
- Výkon: DataLoader, caching, federace pro rozdělení domén, CDN pro persisted GET odpovědi.
- DX: schema registry, automatická generace typů, GraphiQL/Playground, kontraktní testy v CI.
Závěr
GraphQL poskytuje jednotný, silně typovaný kontrakt mezi klienty a backendem a umožňuje přesné, efektivní a evolvující API. Při správném nasazení – s důrazem na governance, bezpečnost, observabilitu a výkon – zjednodušuje vývoj komplexních aplikací, snižuje síťovou režii a urychluje iteraci produktů napříč platformami.