Programování

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.

12. 10. 2026 · 4 min čtení

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).