1. TL;DR — komu co
REST wybierz jeśli masz: jedną aplikację web/mobile, jasne CRUD-y, treści cache'owalne (produkty, artykuły), team który dopiero zaczyna z API.
GraphQL wybierz jeśli masz: 3+ różnych klientów (web + mobile + integrator) pobierających te same dane w różny sposób, dashboardy agregujące dane z 5+ encji, dużą zmienność wymagań frontendowych.
Nie wiesz? Zacznij od REST. Migracja REST → GraphQL przez warstwę BFF jest tańsza niż przebudowa "all-in GraphQL" projektu który skomplikował się przed time.
2. REST API w 2 zdaniach
REST to architektura, w której każdy zasób (klient, faktura, produkt) ma własny URL i obsługuje standardowe metody HTTP (GET/POST/PUT/DELETE). Klient mówi serwerowi "co" chce (np. GET /api/products/123), a serwer decyduje "ile" danych zwrócić.
Wyobraź sobie restaurację z menu komplet zestawów — zamawiasz "Zestaw nr 3" i dostajesz cały zestaw, choć interesuje Cię tylko jeden składnik.
3. GraphQL w 2 zdaniach
GraphQL to język zapytań do API, w którym klient deklaratywnie podaje jakie dokładnie pola chce dostać, w jednym zapytaniu na jeden endpoint (POST /graphql). Serwer wykonuje resolvery dla każdego żądanego pola i składa odpowiedź na miarę.
Wracając do analogii — to bufet, gdzie sam wskazujesz konkretnie "trochę zupy z tego garnka, kawałek tego mięsa, jeden warzywo". Zero marnotrawstwa, ale Twój talerz jest złożony z 10 ruchów łyżką po kuchni.
4. Porównanie 1:1
| Wymiar | REST API | GraphQL |
|---|---|---|
| Endpointy | Wiele: /products, /orders, /users/:id |
Jeden: /graphql |
| Over-fetching | Tak — serwer zwraca pełne obiekty | Nie — klient deklaruje pola |
| Under-fetching | Tak — N requests dla N powiązanych zasobów | Nie — 1 query na wiele encji |
| HTTP cache (CDN) | Działa — GET cacheable | Nie — wszystko POST |
| Type safety | Wymaga OpenAPI/Swagger | Built-in schema |
| Debugging | curl, Postman, devtools Network | Wymaga GraphQL Playground / Apollo Studio |
| Krzywa uczenia | Niska — każdy zna HTTP | Średnia — schema, resolvery, DataLoader |
| Rate limiting | Łatwy — limit per endpoint | Trudny — wymaga query complexity |
| File upload | Natywny — multipart/form-data | Wymaga rozszerzenia (graphql-upload) |
| Real-time | WebSockets / SSE osobno | Subscriptions built-in |
| Ekosystem klient (FE) | fetch / axios — basics | Apollo / Relay — heavy state management |
5. Kiedy REST wygrywa (3 scenariusze)
Scenariusz A: Sklep e-commerce z katalogem 5 000 produktów
Klienci pobierają stronę kategorii (np. /api/products?category=electronics) — endpoint cache'owalny na CDN przez 60 sekund. 90% requestów nigdy nie trafia do bazy. Z GraphQL — każdy POST /graphql jest unique (różne pola, różne filtery) i CDN nie pomaga. Wynik: REST jest 10× tańszy w hostingu i 3× szybszy dla użytkownika końcowego.
Scenariusz B: Integracja z ERP (Comarch, SAP, Symfonia)
ERPy mają natywne REST/SOAP API. Tworzysz nakładkę REST → REST (proxy + mapping). GraphQL by tylko dodał warstwę abstraction bez wartości — i tak wszystkie pola są takie jak w ERP. Integracja ERP / AI u nas — zawsze REST, chyba że klient ma już GraphQL gateway.
Scenariusz C: Aplikacja wewnętrzna B2B, ≤50 użytkowników
Małe portale klienckie (zamówienia, faktury, status realizacji). REST jest prostszy w utrzymaniu, łatwiejszy do testowania (curl, Postman), nie wymaga Apollo Client w przeglądarce. Mniej kodu = mniej bugów. Migracja na GraphQL miałaby sens dopiero przy >500 użytkowników i 3+ klientach.
6. Kiedy GraphQL wygrywa (3 scenariusze)
Scenariusz A: Aplikacja mobilna + web + admin panel + API publiczne
Mobile aplikacja chce minimalne payloady (limit transferu), web chce pełne dane (desktop bandwidth), admin chce admin fields, integratorzy chcą stabilną wersjonowaną API. REST: piszesz 4 różne endpointy (lub query params ?fields=), wersjonujesz każdy, dokumentujesz oddzielnie. GraphQL: jedna schema, każdy klient pyta o swoje. Mniej kodu o 40-60%.
Scenariusz B: Dashboard agregujący 5+ encji
Przykład: panel admin pokazuje dla każdego zamówienia (i) status, (ii) klienta, (iii) faktury, (iv) komentarze obsługi, (v) listy przewozowe. REST: 5 requestów (lub jeden mega-endpoint /orders/123/full). GraphQL: 1 query z 5 polami zagnieżdżonymi. Mobile/wolne łącza: GraphQL wygrywa.
Scenariusz C: Frontend zmienia wymagania co tydzień
Startup w fazie product-market fit. Marketing dziś prosi "pokaż na karcie produktu też opinie", jutro "i miniatury wariantów". REST: dev musi modyfikować endpoint /products/:id lub dodawać ?include=reviews,variants. GraphQL: frontend dodaje pola do query, backend nic nie robi (resolvery już istnieją). Szybciej iteracja, mniej commits w backendzie.
7. Hybryda REST + GraphQL — najczęstszy realny setup
W praktyce 80% projektów które prowadzę używa obu:
- REST dla webhooków, file upload, integracji z ERP/CRM, payment gateway callbacks, public API dla partnerów (łatwiejsze do dokumentacji)
- GraphQL jako BFF (Backend For Frontend) dla aplikacji webowej i mobile — resolvery wewnętrznie wywołują REST
8. Pułapki GraphQL których nikt Ci nie powie
N+1 query problem
Zapytanie GraphQL: { orders { id, customer { name } } } dla 100 zamówień = 1 query do orders + 100 queries do customers. Wymaga DataLoader (batching). Bez tego — performance kill. W REST jawnie piszesz JOIN.
Query complexity attacks
Atakujący wysyła zagnieżdżenie 10 poziomów: { user { posts { comments { user { posts { ... } } } } } }. Bez limitów — Twój serwer się dławi. Wymaga graphql-depth-limit i graphql-cost-analysis. Mało kto pamięta na początku projektu.
Brak HTTP cache
Każde zapytanie GraphQL to POST do /graphql. CDN edge cache (Cloudflare, Vercel) nie zadziała out-of-the-box. Trzeba @cacheControl + persisted queries albo automatic persisted queries (APQ). To dodatkowy setup, którego REST nie wymaga.
Versioning
GraphQL "nie ma wersji" — zmieniasz schema, klient się dostosowuje. W praktyce: kiedy musisz zmienić nazwę pola, dodajesz nowe pole + deprecate stare + czekasz miesiącami. To też wersjonowanie, tylko bardziej rozmazane czasowo.
9. Decision matrix dla aplikacji B2B
Po przejściu przez poprzednie sekcje, użyj tej macierzy:
| Twoja sytuacja | Wybierz |
|---|---|
| 1 klient (tylko web) | REST |
| 2 klienty (web + mobile), prosty CRUD | REST |
| 3+ klienty (web + mobile + integrator + admin) | GraphQL (lub REST + BFF GraphQL) |
| Aplikacja z dużym CMS/katalogiem cache'owalnym | REST |
| Dashboard agregujący 5+ encji | GraphQL |
| Integracja z ERP (Comarch, SAP) | REST |
| Wymagania frontowe zmieniają się tygodniowo | GraphQL |
| Team junior, krótki deadline | REST |
| Real-time updates (subscriptions) potrzebne | GraphQL (lub REST + WebSocket osobno) |
Wybór API dla Twojej aplikacji B2B
Mam 20+ lat doświadczenia w B2B, certyfikat Comarch ERP XL, projektowałem i migracje REST↔GraphQL w skali 10-500 użytkowników. Bezpłatna 30-min rozmowa — porozmawiamy o Twojej architekturze i podpowiem co wybrać.
Opisz projekt słowami → AI generuje wstępną wycenę + scope od ręki. Bez czekania.