GraphQL vs REST: te same dane pobrane na dwa sposoby | We.Inc
Porównaj GraphQL i REST na tych samych danych pobranych na dwa sposoby: liczba żądań, over-fetching, cache, sposób zwracania błędów i tabela pomagająca wybrać jedno z nich.
REST udostępnia wiele adresów URL, po jednym na zasób, a serwer decyduje, co zawiera każda odpowiedź. GraphQL udostępnia jeden endpoint, zwykle /graphql, do którego klient wysyła zapytanie wymieniające dokładnie te pola, których potrzebuje. REST dostaje darmowy cache HTTP według URL; GraphQL oszczędza kolejne żądania i pomija nieużywane pola kosztem większej pracy serwera.
W skrócie
Temat
REST
GraphQL
Endpointy
Jeden URL na zasób
Jeden endpoint, często /graphql
Kto wybiera pola
Serwer
Klient, w zapytaniu
Powiązane dane
Często kilka żądań
Zagnieżdżone w jednym zapytaniu
Cache HTTP
Wbudowany dla GET według URL
Wymaga zapytań GET, persisted queries lub cache po stronie klienta
Błędy
Głównie kody statusu HTTP
Tablica errors, często obok częściowych danych
Schemat
Opcjonalny (OpenAPI)
Wymagany i typowany
Porównanie poniżej pobiera ten sam ekran danych na oba sposoby. Wybierz scenariusz, aby zobaczyć wywołania REST, które wykonałby klient, obok jednego zapytania GraphQL, które je zastępuje, oraz to, co każda odpowiedź pomija lub dodaje.
Wybierz scenariusz, na przykład stronę profilu z ostatnimi wpisami.
Przeczytaj żądania REST po lewej i zapytanie GraphQL po prawej.
Porównaj liczbę żądań pokazaną pod panelami.
Przeczytaj notatkę, aby zobaczyć, gdzie każdy styl wysyła więcej danych, niż potrzebuje ekran.
Nie przenoś działającego API REST na GraphQL tylko dla mody. Zysk pojawia się, gdy wiele różnych ekranów potrzebuje różnych wycinków powiązanych danych.
Udostępnij stabilne pole id w każdym typie GraphQL, aby biblioteki klienckie mogły według niego normalizować swój cache.
Sprawdzaj tablicę errors w każdej odpowiedzi GraphQL, nawet gdy status to 200 i dane są obecne.
Ustaw limity głębokości i kosztu na publicznym endpoincie GraphQL, bo jedno zagnieżdżone zapytanie może zlecić bardzo dużo pracy.
Najczęściej zadawane pytania
Czy GraphQL jest szybszy niż REST?
Sam z siebie nie. Może ograniczyć liczbę żądań i rozmiar danych dla ekranów potrzebujących powiązanych danych, ale rozwiązanie każdego zapytania może kosztować serwer więcej. Dobrze zaprojektowany endpoint REST dla jednego ekranu może być równie szybki.
Dlaczego błąd GraphQL wraca ze statusem 200?
Jedno pole może się nie powieść, a inne tak, więc serwer zwraca posiadane dane oraz tablicę errors. Wytyczne GraphQL over HTTP używają 2xx dla częściowego sukcesu; serwery odpowiadające z application/graphql-response+json używają 400, gdy żądanie nie przejdzie walidacji.
Czy CDN może cache'ować odpowiedzi GraphQL?
Tak, jeśli zapytania są wysyłane metodą GET, na co serwery mogą pozwalać tylko dla zapytań. Długie zapytania mogą przekraczać limity URL, więc zespoły używają persisted queries, które wysyłają krótki hash zamiast całego dokumentu.
Czy mogę używać obu w jednym produkcie?
Wiele zespołów tak robi. Przesyłanie plików, webhooki i proste publiczne zasoby często zostają jako trasy REST, a ekrany aplikacji czytają dane przez warstwę GraphQL, która pod spodem może wywoływać te same usługi.
Czy GraphQL potrzebuje własnej bazy danych?
Nie. Serwer GraphQL to warstwa resolverów, małych funkcji, które pobierają każde pole stamtąd, gdzie znajdują się dane: z bazy danych, usługi REST lub pliku. Schemat opisuje kształty, nie sposób przechowywania.
Over-fetching i under-fetching
Endpoint REST zwraca stały kształt. Ekran listy, który pokazuje tylko imiona, i tak pobiera każde pole każdego użytkownika, co nazywa się over-fetchingiem. Ekran szczegółów, który potrzebuje użytkownika, jego wpisów i liczby komentarzy pod każdym wpisem, może wymagać kilku wywołań, co nazywa się under-fetchingiem.
GraphQL przenosi ten wybór na klienta. Zapytanie wymienia pola, a serwer zwraca dokładnie taki kształt i nic więcej. Ceną jest to, że serwer musi obsłużyć każdą kombinację pól, o którą może poprosić klient.
Cache działa inaczej
W REST URL jest kluczem cache. Przeglądarki i CDN mogą przechować odpowiedź GET i użyć jej ponownie, bo GET i HEAD to metody podlegające cache. Większość ruchu GraphQL to POST na jeden URL, którego te cache nie przechowują.
Klienci GraphQL nadrabiają to w aplikacji: dzielą odpowiedzi na obiekty i przechowują je według id, więc dwa zapytania dotyczące tego samego użytkownika współdzielą jeden zapisany rekord. graphql.org zaleca globalnie unikalne pole id właśnie z tego powodu.
Błędy i kody statusu
REST opiera się na linii statusu: 404 dla brakującego rekordu, 401 dla niezalogowanego użytkownika, 422 dla błędnych danych wejściowych. Klienci mogą rozgałęziać logikę na podstawie samego kodu.
Odpowiedź GraphQL ma klucz data, klucz errors albo oba. Problem ze składnią lub walidacją daje errors bez data. Awaria wewnątrz jednego pola daje częściowe dane, w których to pole ma wartość null, oraz wpis błędu, którego path na nie wskazuje.
Który wybrać
Tabela decyzyjna
Twoja sytuacja
Przemawia za
Publiczne API, które firmy zewnętrzne wywołują przez curl
REST
Wiele ekranów, z których każdy potrzebuje innych powiązanych danych
GraphQL
Intensywny cache CDN dla ruchu odczytu
REST albo GraphQL z persisted queries przez GET
Klienci mobilni w wolnych sieciach
GraphQL, mniej żądań
Prosty CRUD na kilku tabelach
REST
Kilka usług backendowych za jednym wejściem
GraphQL jako warstwa bramy
Co przesyła się przez sieć
Żądanie GraphQL przez fetch
Każda operacja to POST z JSON-em zawierającym klucze query i variables, wysłany do jednego endpointu. Nagłówek Accept prosi o nowszy typ odpowiedzi GraphQL, a zwykły JSON jest rozwiązaniem zapasowym.
Częściowa odpowiedź GraphQL
Jedno pole się nie powiodło, więc ma wartość null, a wpis w errors wskazuje je przez path. Reszta danych i tak dotarła.
Profil z wpisami
REST potrzebuje drugiego wywołania dla wpisów, a obie odpowiedzi zawierają każde pole, które dołącza serwer. Zapytanie GraphQL zwraca tylko imię, awatar i tytuły trzech wpisów.
Tylko imiona
Dla prostej listy wywołanie REST to w obu przypadkach jedno żądanie, ale wysyła całe rekordy użytkowników. GraphQL wysyła tylko dwa żądane pola.
Wpis z komentarzami i autorami
Bez dedykowanego endpointu REST przechodzi drzewo o jeden poziom na żądanie, a pobranie autora każdego komentarza może oznaczać jedno dodatkowe wywołanie na komentarz. GraphQL zagnieżdża całe drzewo w jednym zapytaniu.
Utwórz wpis
Zapisy wyglądają podobnie: po jednym żądaniu. REST używa metody POST na URL kolekcji; GraphQL wysyła mutację, nadal jako HTTP POST, i wybiera, które pola nowego wpisu zwrócić.
Te same dane na dwa sposoby
Wybierz scenariusz
Żądania REST
Zapytanie GraphQL
Kopiuj żądania REST
Kopiuj zapytanie GraphQL
REST: liczba żądań {n}. GraphQL: liczba żądań {v}.