GraphQL vs. REST: rozdíly, výhody a kdy se GraphQL vyplatí
Věcné srovnání GraphQL a REST API: overfetching, schéma a typy, cachování, N+1 a DataLoader, bezpečnost dotazů a praktické rozhodovací otázky.
GraphQL vznikl ve Facebooku jako odpověď na konkrétní problém: mobilní aplikace potřebovaly z mnoha zdrojů přesně tolik dat, kolik zobrazí, a v jednom požadavku. Neznamená to, že je nástupcem RESTu. Je to jiný nástroj s jinými kompromisy.
Princip ve dvou příkladech
REST
Pro zobrazení článku s autorem a třemi komentáři voláte více endpointů:
GET /articles/42
GET /users/7
GET /articles/42/comments?limit=3
Každý vrací pevně danou strukturu – často víc polí, než potřebujete (overfetching), a přitom ne všechno najednou (underfetching).
GraphQL
Jeden endpoint (typicky POST /graphql), klient popíše, co chce:
query ArticleDetail($id: ID!) {
article(id: $id) {
title
publishedAt
author { name avatarUrl }
comments(first: 3) { body author { name } }
}
}
Odpověď má přesně tento tvar:
{
"data": {
"article": {
"title": "GraphQL v praxi",
"publishedAt": "2026-10-12",
"author": { "name": "Jana", "avatarUrl": "/a/7.png" },
"comments": [ { "body": "Díky!", "author": { "name": "Petr" } } ]
}
}
}
Schéma
Základem GraphQL je silně typované schéma:
type Article {
id: ID!
title: String!
publishedAt: String
author: User!
comments(first: Int = 10): [Comment!]!
}
type Query {
article(id: ID!): Article
}
type Mutation {
createComment(articleId: ID!, body: String!): Comment!
}
Schéma slouží jako dokumentace i kontrakt. Nástroje z něj generují typy pro TypeScript, klienti mají automatické doplňování a server odmítne dotaz na neexistující pole ještě před spuštěním.
Srovnání
| REST | GraphQL | |
|---|---|---|
| Endpointy | mnoho, podle zdrojů | obvykle jeden |
| Tvar odpovědi | určuje server | určuje klient |
| HTTP cache, CDN | přirozeně (GET + URL) | složitější (většinou POST) |
| Status kódy | nesou význam | často vždy 200, chyby v poli errors |
| Typy a introspekce | volitelně (OpenAPI) | vestavěné |
| Upload souborů | jednoduchý | není ve specifikaci, řeší se rozšířením |
| Náročnost serveru | předvídatelná | závisí na dotazu klienta |
| Křivka učení | nízká | vyšší (schéma, resolvery, klient) |
Problémy, které GraphQL přináší
N+1 v resolverech
Každé pole má resolver. Když dotaz chce 50 článků a u každého autora, naivní implementace zavolá databázi 51krát. Standardním řešením je DataLoader – posbírá ID z jednoho „tiku“ a načte je jedním dotazem:
import DataLoader from "dataloader";
const userLoader = new DataLoader(async (ids) => {
const users = await db.query("SELECT * FROM users WHERE id = ANY($1)", [ids]);
const byId = new Map(users.rows.map((u) => [u.id, u]));
return ids.map((id) => byId.get(id) ?? null);
});
const resolvers = {
Article: {
author: (article) => userLoader.load(article.author_id),
},
};
DataLoader vytvářejte pro každý požadavek zvlášť, jinak sdílíte cache mezi uživateli.
Drahé a škodlivé dotazy
Klient může poslat hluboce vnořený dotaz (author { articles { author { articles ... } } }), který server zahltí. Ochrana:
- limit hloubky dotazu,
- analýza složitosti (každé pole má „cenu“, dotaz nad limit se odmítne),
- povinné stránkování u seznamů,
- persisted queries – v produkci server přijímá jen předem registrované dotazy podle hashe. Pro vlastní aplikaci (ne veřejné API) je to nejúčinnější ochrana.
Zvažte také vypnutí introspekce v produkci u neveřejných API.
Autorizace
Oprávnění kontrolujte na úrovni dat (v resolverech nebo v doménové vrstvě), ne podle názvu dotazu. Stejná data mohou být dosažitelná různými cestami grafem.
Cachování
GET požadavky REST API cachuje prohlížeč, CDN i reverzní proxy bez další práce. U GraphQL se cache přesouvá na klienta (Apollo Client, urql normalizují data podle ID) a na server. Persisted queries umožňují posílat dotazy přes GET a tím vrátit část HTTP cache.
Monitoring a chyby
Všechno je POST /graphql se statusem 200, takže běžné metriky podle URL a status kódu nefungují. Potřebujete logování podle názvu operace (proto dotazy pojmenovávejte: query ArticleDetail) a sledování pole errors.
Kdy se GraphQL vyplatí
- Více klientů (web, iOS, Android) s rozdílnými potřebami nad stejnými daty.
- Bohatý, provázaný datový model a obrazovky skládající data z mnoha zdrojů.
- API gateway nad několika backendovými službami.
- Tým, který investuje do typů a generování kódu na frontendu.
Kdy zůstat u RESTu
- Jednoduché CRUD API nebo jeden frontend.
- Veřejné API pro integrace – REST zná každý a dobře se cachuje.
- Webhooky, stahování souborů, jednoduché služby mezi servery.
- Malý tým bez kapacity řešit složitost dotazů, DataLoadery a bezpečnostní limity.
Prakticky
Nemusíte volit jen jedno. Běžná a rozumná architektura je REST pro veřejné API a webhooky a GraphQL jako „backend for frontend“ pro vlastní aplikace. Pokud začínáte, postavte nejdřív dobře navržené REST API (viz návrh REST API) a ke GraphQL přejděte, až narazíte na problémy, které skutečně řeší.
Oblíbené implementace: Apollo Server a GraphQL Yoga (Node.js), Strawberry a Graphene (Python), Lighthouse (Laravel), gqlgen (Go).