Architektura · API · Aplikacje B2B

REST API vs GraphQL dla aplikacji B2B — kiedy które wybrać

Pytanie nie brzmi "co jest lepsze". Brzmi "co pasuje do mojej aplikacji". REST i GraphQL rozwiązują różne problemy — wybór nie ma jednoznacznej odpowiedzi technicznej, tylko biznesową. Po 20 latach budowania aplikacji B2B (i kilkudziesięciu migracjach w obie strony) zebrałem decision tree, które działa w 95% przypadków.

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
Wzorzec BFF (Backend For Frontend): postaw cienki layer GraphQL nad istniejącym REST API. Każdy resolver pobiera dane z REST endpointu i transformuje pod potrzeby frontu. Migracja może trwać 6-12 mies., zero ryzyka — stary REST zostaje, frontend stopniowo przechodzi na GraphQL.

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 CRUDREST
3+ klienty (web + mobile + integrator + admin)GraphQL (lub REST + BFF GraphQL)
Aplikacja z dużym CMS/katalogiem cache'owalnymREST
Dashboard agregujący 5+ encjiGraphQL
Integracja z ERP (Comarch, SAP)REST
Wymagania frontowe zmieniają się tygodniowoGraphQL
Team junior, krótki deadlineREST
Real-time updates (subscriptions) potrzebneGraphQL (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.

Podobne artykuły