Architektura
ArchitekturaUżywanie komponentów zamiast grafów

Używanie komponentów zamiast grafów

Gato GraphQL nie używa grafów do reprezentowania modelu danych. Zamiast tego używa komponentów.

To nie jest nieoczekiwane podejście. Pod tytułem Thinking in Graphs, projekt GraphQL stwierdza (wyróżnienie dodane):

Grafy są potężnymi narzędziami do modelowania wielu zjawisk ze świata rzeczywistego, ponieważ przypominają nasze naturalne modele mentalne i słowne opisy leżącego u podstaw procesu. Dzięki GraphQL modelujesz swoją domenę biznesową jako graf poprzez zdefiniowanie schematu; w ramach schematu definiujesz różne typy węzłów i sposób ich łączenia/powiązania ze sobą. Po stronie klienta tworzy to wzorzec podobny do programowania obiektowego: typy odwołujące się do innych typów. Po stronie serwera, ponieważ GraphQL definiuje tylko interfejs, masz swobodę używania go z dowolnym backendem (nowym lub istniejącym!).

Wniosek z tej definicji jest następujący:

Nawet jeśli odpowiedź ma kształt grafu, nie oznacza to, że dane są faktycznie reprezentowane jako graf podczas pracy z nimi po stronie serwera. Graf jest jedynie modelem mentalnym, a nie rzeczywistą implementacją.

To dobra wiadomość, ponieważ praca z grafami (lub drzewami) nie jest trywialna. Komponenty natomiast są znacznie prostsze do zaimplementowania i zapewniają te same korzyści.

Upraszczanie modelu danych za pomocą komponentów

Używanie komponentów do reprezentowania struktury danych po stronie serwera jest optymalne pod względem prostoty, ponieważ pozwala skonsolidować różne modele danych w jedną strukturę. Zamiast mieć przepływ taki jak ten:

budowanie query do zasilenia komponentów (klient) => przetwarzanie danych jako graf/drzewo (serwer) => dostarczanie danych do komponentów (klient)

...nasz przepływ będzie wyglądał tak:

komponenty (klient) => komponenty (serwer) => komponenty (klient)

Jest to możliwe, ponieważ żądanie GraphQL można postrzegać jako posiadające strukturę danych "hierarchii komponentów", w której każdy typ obiektu reprezentuje komponent, a każde pole relacji od jednego typu obiektu do innego reprezentuje komponent owijający inny komponent.

Użyjmy przykładu, aby zwizualizować tę zależność między komponentem a query GraphQL. Powiedzmy, że chcemy zbudować następujący widget "Wyróżniony reżyser":

Widget Wyróżniony reżyser

Używając Vue lub React (lub dowolnej innej biblioteki opartej na komponentach), najpierw zidentyfikowalibyśmy komponenty. W tym przypadku mielibyśmy zewnętrzny komponent <FeaturedDirector> (na czerwono), który opakowuje komponent <Film> (na niebiesko), który z kolei opakowuje komponent <Actor> (na zielono):

Identyfikowanie komponentów w widgecie

Pseudokod będzie wyglądał tak:

<!-- Component: <FeaturedDirector> -->
<div>
  Country: {country}
  {foreach films as film}
    <Film film={film} />
  {/foreach}
</div>
 
<!-- Component: <Film> -->
<div>
  Title: {title}
  Pic: {thumbnail}
  {foreach actors as actor}
    <Actor actor={actor} />
  {/foreach}
</div>
 
<!-- Component: <Actor> -->
<div>
  Name: {name}
  Photo: {avatar}
</div>

Następnie identyfikujemy, jakie dane są potrzebne dla każdego komponentu. Dla <FeaturedDirector> potrzebujemy name, avatar i country. Dla <Film> potrzebujemy thumbnail i title. A dla <Actor> potrzebujemy name i avatar:

Identyfikowanie właściwości danych dla każdego komponentu

I budujemy nasze query GraphQL, aby pobrać wymagane dane:

query {
  featuredDirector {
    name
    country
    avatar
    films {
      title
      thumbnail
      actors {
        name
        avatar
      }
    }
  }
}

Jak można zauważyć, istnieje bezpośrednia zależność między powyższą hierarchią komponentów a tym query GraphQL.