Graphql jest coraz popularniejszy w aplikacjach. Pozwala na pobieranie dokładnie tych danych, jakich potrzebujemy. W jednym z poprzednich postów pokazałem jak to zaimplementować na backendzie. Dziś przyszedł czas na frontend.
Instalacja i konfiguracja
Najpierw rzeczy oczywiste - instalacja i konfiguracja potrzebnych bibliotek. Będę oczywiście konfigurował projekt napisany w React.
Do poprawnego działania potrzebujemy tzw.: klienta. Jest to w minimalnej konfiguracji adres serwera graphql, z którego będziemy pobierać dane i rodzaj cache'a. Będziemy z niego korzystać przy każdej operacji.
Uwaga! URL do Graphql najlepiej przekazywać w zmiennej środowiskowej
Najlepiej jest wyciągnąć konfigurację klienta do osobnego pliku. Dlaczego? Ponieważ będziemy mogli go importować w wielu miejscach. Możemy również mieć kilka klientów w jednej aplikacji.
Dodatkowo w React możemy skorzystać z Contextu, by dostarczyć domyślnego klienta i uprościć pracę.
Nic nie stoi na przeszkodzie, by osobne części systemu korzystały z różnych Provider'ów. Warto zwrócić uwagę, iż możemy przekazać tylko jedną instancję klienta. Powoduje to, iż w sytuacji, gdy korzystamy z kilku klientów, może to być nieintuicyjne.
Rodzaje operacji
W GraphQL mamy kilka rodzajów operacji, które możemy wykonać:
- Query - do pobierania danych
- Mutation - do aktualizacji danych
- Subscription - do nasłuchiwania na dane
Do każdej z tych operacji mamy odpowiednie funkcje, które możemy wykorzystać. Dziś skupię się na Query i Mutation
Query
Najprostszą operacją jest pobieranie danych. W GraphQL polega to na wysłaniu odpowiedniego Query. W Apollo Graphql mamy dostępne dwa hooki: useQUery i useLazyQuery. Zacznę od tego pierwszego.
Do wykonania dowolnej operacji potrzebujemy query z Graphql'a. Tworzymy je przy pomocy funkcji gql. Sam hook wymaga od nas podania tylko tego query do poprawnego działania. Ale oprócz tego możemy przekazać obiekt z dodatkowymi ustawieniami. To z czego ja najcześciej korzystam to:
- variables - do przekazywania zmiennych np.: filtry
- fetchPolicy - do ustawienia sposobu, w jaki chce pobrać dane - czy zawsze to ma być zapytanie na backend, czy chcemy wykorzystać cache.
To, co dostajemy to obiekt z odpowiednimi polami. Do tych najczęściej wykorzystywanych można zaliczyć:
- loading - true jeżeli zapytanie jest w trakcie
- error - jeżeli w trakcie zapytania wystąpił błąd, to tutaj będą informacje o nim
- data - dane zwrócone z backendu
Inne interesujące pola to:
- refetch - do ponownego uruchomienia query z tymi samymi zmiennymi.
- fetchMore - wykorzystywane do paginacji, by pobrać kolejną porcję danych
Ten hook zawsze wykonuje się po zamontowaniu komponentu na stronie. jeżeli chcesz pobrać dane w wyniku jakiejś akcji to musisz wykorzystać LazyQuery
LazyQuery
To jest rozszerzenie poprzedniego hooka. Różni się tylko tym, iż zwraca tablicę zamiast obiektu i nie wykonuje się automatycznie. Za to pierwszy element tablicy jest funkcją, która pozwala na pobranie danych. Wygląda to następująco:
Reszta elementów jest bez zmian.
Mutation
Na sam koniec zostawiłem mutacje. jeżeli chodzi o strukturę, to wygląda podobnie do LazyQuery. Czyli jako rezultat hooka dostajemy tablicę, gdzie pierwszym elementem jest funkcja, która umożliwia wykonanie mutacji.
Tak samo wygląda obiekt z rezultatem wykonania mutacji. Dodatkowym elementem jest flaga called. A jak przekazać zmienne do mutacji? Bardzo prosto - podczas jej wywoływania.
Możemy też tego użyć w inny sposób. Zamiast pobierać dane bezpośrednio z hooka, możemy je pobierać z funkcji mutującej.
Ciekawym parametrem jaki możemy przekazać w mutacji, obok variables, jest refetchQueries. Pozwala na wykonanie query, po tym jak się wykona mutacja. Możesz tego użyć np.: do odświeżenia widoku po tym, jak użytkownik zaktualizował dane. Przykładowy kod wygląda następująco: