Kompletny przewodnik po zapytaniach GraphQL

Obecnie GraphQL staje się coraz bardziej popularny. Chciałbym pokazać, jak zacząć z nim korzystać i jak wysyłać zapytania o dane do interfejsów API GraphQL

GraphQL pomaga zapobiegać przeładowaniu danych. W przeciwieństwie do Restful API, GraphQL pozwala na określenie pól, które będą odbierane z serwera. Spowoduje to szybszą komunikację i mniejszy ruch w sieci, co znacznie skróci czas reakcji. Istnieją dwa podstawowe typy operacji w GraphQL: zapytania i mutacje.

Do odczytu danych używa się zapytań, a do ich modyfikacji – mutacji. Operacja jest prostym ciągiem znaków, który pozwala serwerowi analizować i odpowiadać na dane w obu przypadkach.

Czym jest zapytanie graphQL?

Każdy interfejs API GraphQL ma schemat GraphQL. Schemat opisuje wygląd danych i dozwolone operacje. Jeśli więc masz obiekt cars w swoim schemacie, możesz zapytać o niego. Zapytanie graphQL wyglądałoby następująco:

query getCars {
  cars {
    brand,
    color
  }
}

W powyższym przykładzie widać pojedyncze zapytanie graphQL o nazwie getCars. W tej operacji GraphQL zdefiniowano zapytanie, które pobiera dwa pola typu samochodów: brand i color. Więcej szczegółów na temat zapytań GraphQL przedstawię w tym artykule, ale najpierw zobaczmy, jak można wykonywać zapytania i korzystać z dowolnego interfejsu API GraphQL.

Wymagania wstępne

W tym artykule chciałbym pokazać dwie typowe rzeczy: użycie zapytania GraphQL po stronie klienta i napisanie podstawowego zapytania przy użyciu NodeJS.

GraphQL API

W pierwszym przypadku nie potrzebujesz interfejsu API GraphQL. Do eksperymentowania można użyć niektórych publicznych interfejsów API GraphQL.

Dobrze zbudowanym API, z którym można zacząć ćwiczyć, jest API SpaceX: https://api.spacex.land/graphql/

Serwer GraphQL

W przypadku, gdy chcesz utworzyć interfejs API GraphQL (z zapytaniami), musisz utworzyć serwer GraphQL. Zamierzam pokazać prosty przykład zbudowany przy użyciu Node i ExpressJS.

Gdzie można uruchomić zapytanie w GraphQL?

Zacznijmy od wykorzystania interfejsu API SpaceX, aby poznać podstawy zapytań graphQL. Masz co najmniej cztery opcje gry z tym API:

  • przy użyciu GraphQL Playground
  • przy użyciu GraphiQL Explorer
  • przy użyciu Apollo Studio
  • przy użyciu rozszerzeń Chrome, takich jak Altair GraphQL

GraphQL Playground i GraphiQL Explorer

Są to narzędzia, które pozwalają bawić się każdym interfejsem API graphQL. Na przykład, po wpisaniu tego adresu URL w przeglądarce: https://api.spacex.land/graphql/, wyświetli się GraphiQL explorer. Można tam przeglądać schematy, czytać dokumentację, uruchamiać zapytania, mutacje itd. GraphQL Playground ma prawie taki sam zestaw funkcji.

Możesz skonfigurować plac zabaw na poziomie projektu lub zainstalować go w aplikacji macOS.

Uwaga: GraphQL Playground i GraphiQL łączą siły. Więcej informacji tutaj: https://github.com/graphql/graphql-playground/issues/1143

Apollo Studio

W przypadku tworzenia serwera graphQL przy użyciu apollo-serverbędziesz mógł użyć Apollo Studio do sprawdzenia swojego API.

Klient Altair GraphQL

Klient Altair to rozszerzenie Chrome, które umożliwia przeglądanie specyfikacji GraphQL, wysyłanie zapytań o wszystkie dane, wysyłanie mutacji, korzystanie z subskrypcji itp.

Dzisiaj użyję GraphiQL API, ponieważ API SpaceX je udostępnia. Zazwyczaj używane są narzędzia dostarczane z serwerami project/graphQL. Jeśli rozwijasz swój projekt, możesz wybrać własny Playground, ale nie ma to znaczenia, ponieważ wkrótce oba narzędzia zostaną połączone.

Rozszerzenie Chrome jest dobrym wyborem, jeśli chcesz czasami szybko sprawdzić i nie masz możliwości korzystania z żadnego placu zabaw, ale ogólnie możesz użyć tego rozszerzenia i nie korzystać z placów zabaw. Wszystkie te techniki są wystarczająco dobre.

dane graphql

Zapytanie o dane

Teoria, teoria, teoria…. Skończmy z tym i ubrudzmy sobie ręce!

Spróbujmy dotrzeć do wszystkich użytkowników!

{
  users {
    name
    rocket
  }
}

Proste?

W powyższym przykładzie widać proste zapytanie. Obiekty ” users ” mogą być używane do żądania danych o wszystkich dostępnych użytkownikach – „users” jest obiektem w języku GraphQL. Obiekty przechowują dane o jednostce. Każdy obiekt posiada pola. W naszym przypadku użyliśmy pola name i rocket, ale istnieje więcej pól dla obiektów użytkowników. Zapoznaj się z dokumentacją:

id: uuid!
name: String
rocket: String
timestamp: timestampt!
twitter: String

Niektóre pola nie mogą być puste (null), a wykrzyknik określa to na końcu. Oznacza to, że na przykład identyfikator nie może mieć wartości null lub być niezdefiniowany. Jeśli tak będzie, GraphQL zgłosi błąd.

Wyniki poniższego zapytania mogą wyglądać następująco:

{
  "data": {
    "users": [
      {
        "name": "sherlock holmes",
        "rocket": "221B Baker Street"
      },
      {
        "name": "sherlock holmes",
        "rocket": "221B Baker Street"
      },
      {
        "name": "sherlock holmes",
        "rocket": "221B Baker Street"
      },
      {
        "name": "sherlock holmes",
        "rocket": "221B Baker Street"
      },
      {
        "name": "User_14211338",
        "rocket": "Space_101010101"
      },
      {
        "name": "Elanthamil",
        "rocket": "Elanthamil"
      }
    ]
  }
}

Gratulacje! Wykonałeś swoje pierwsze zapytanie graphQL! Jesteś na dobrej drodze do zostania mistrzem GraphQL, naprawdę!

Pierwsze zapytanie - droga do zostania mistrzem graphQL

Zapytanie ze zmiennymi

W poprzednim przykładzie widziałeś proste zapytanie (anonimowa operacja). Teraz zrobimy coś bardziej skomplikowanego, na przykład zapytanie ze zmiennymi. Jeśli chcesz przekazać zmienną do zapytania graphQL, możesz przekazać je jako parametry:

{
  users(limit: 10, order_by: {name: asc}) {
    name
    rocket
  }
}

Działa to w Playground, ale nie jest zbyt wartościowe, ponieważ wartości zmiennych są zakodowane na stałe. Zdefiniujmy zapytanie nazwane przy użyciu (zaskakującego) słowa kluczowego zapytania:

query getUsers($limit: Int, $orderBy: [users_order_by!]) {
  users(limit: $limit, order_by: $orderBy) {
    name
    rocket
  }
}

Jak widać, przekazaliśmy dwie zmienne: $limit , która jest typu Int, oraz $orderBy, która jest typu [users_order_by!].

Typy mogą być prymitywne, takie jak String, Int, Float, Boolean i ID, a także można zadeklarować niestandardowe typy w schemacie graphQL .

Wykrzyknik oznacza, że ten parametr nie może być pusty. Masz specjalne miejsce o nazwie „Zmienne zapytania” (na dole). Pomocne będzie umieszczenie tam zmiennej zapytania. W przeciwnym razie zapytanie zgłosi błąd.

Można również określić domyślną zmienną w GraphQL. Działa tylko w przypadku argumentów niewymaganych. Zobacz:

query getUsers($limit: Int = 5, $orderBy: [users_order_by!]) {
  users(limit: $limit, order_by: $orderBy) {
    name
    rocket
  }
}

Obiekty zagnieżdżone

W zapytaniu można żądać zagnieżdżonych pól (w oparciu o schemat graphQL):

query getLaunchesPast($limit: Int = 2) {
  launchesPast(limit: $limit) {
    mission_name
    launch_date_local
    launch_site {
      site_name_long
    }
    rocket {
      rocket_name
      first_stage {
        cores {
          flight
          core {
            reuse_count
            status
          }
        }
      }
    }
  }
}

Wyniki mogą wyglądać następująco:

{
  "data": {
    "launchesPast": [
      {
        "mission_name": "Starlink-15 (v1.0)",
        "launch_date_local": "2020-10-24T11:31:00-04:00",
        "launch_site": {
          "site_name_long": "Cape Canaveral Air Force Station Space Launch Complex 40"
        },
        "rocket": {
          "rocket_name": "Falcon 9",
          "first_stage": {
            "cores": [
              {
                "flight": 7,
                "core": {
                  "reuse_count": 6,
                  "status": "unknown"
                }
              }
            ]
          }
        }
      },
      {
        "mission_name": "Sentinel-6 Michael Freilich",
        "launch_date_local": "2020-11-21T09:17:00-08:00",
        "launch_site": {
          "site_name_long": "Vandenberg Air Force Base Space Launch Complex 4E"
        },
        "rocket": {
          "rocket_name": "Falcon 9",
          "first_stage": {
            "cores": [
              {
                "flight": 1,
                "core": {
                  "reuse_count": 0,
                  "status": null
                }
              }
            ]
          }
        }
      }
    ]
  }
}

Dyrektywy

Dyrektywy umożliwiają wykonywanie zapytań warunkowych dla obiektów. Istnieją dwa rodzaje dyrektyw: include i skip. Do zapytania można przekazać zmienną bool, a następnie użyć tej zmiennej w dyrektywie. Zobacz, jak to działa:

query getLaunchesPast($limit: Int = 2, $withRockets: Boolean = false) {
  launchesPast(limit: $limit) {
    mission_name
    launch_date_local
    launch_site {
      site_name_long
    }
    rocket @include(if: $withRockets) {
      rocket_name
      first_stage {
        cores {
          flight
          core {
            reuse_count
            status
          }
        }
      }
    }
  }
}

Uwaga: Niestety, API SpaceX korzysta ze starszej wersji narzędzi GraphQL i te dyrektywy nie są tam obsługiwane.

Uwaga 2: Implementacje GraphQL Server mogą również dodawać eksperymentalne funkcje poprzez definiowanie zupełnie nowych dyrektyw.

Jak działają zapytania GraphQL?

Gdy chcesz wysłać zapytanie z interfejsu użytkownika, do serwera graphQL wysyłane jest pojedyncze żądanie. GraphQL pobiera zapytanie i sprawdza, czego potrzebujesz, a następnie funkcja resolver pobiera wszystkie powiązane dane i zwraca obiekt JSON.

Teoretycznie można wysłać żądanie jako zwykłe żądanie HTTP, ale dobrą praktyką jest użycie jednego z klientów GraphQL do komunikacji z serwerem. Szczerze mówiąc, w prawdziwych projektach należy używać klienta GraphQL na interfejsie użytkownika, ponieważ zapewnia on wiele korzyści, takich jak buforowanie, mechanizmy wysyłania zapytań, mutacje itp.

type Query

Jak utworzyć zapytanie w GraphQL?

Pokazałem, jak wysłać zapytanie. Teraz stwórzmy nasz serwer GraphQL i zdefiniujmy zapytanie.

Będziemy używać NodeJS i Apollo Server do tworzenia aplikacji.

Aplikacja to duże słowo. Będą to podstawowe rzeczy. Utwórzmy zapytanie, które zwraca Hello World. To fantastyczny pomysł, prawda?

Konfiguracja projektu

Zainicjujmy nowy projekt poleceniem npm init . Następnie zainstalujmy wszystkie niezbędne zależności:

$ npm install apollo-server graphql --save

Utwórz plik index.js

Utwórz plik index.js w katalogu src (utwórz również katalog).

Umieść te importy na początku pliku:

const { ApolloServer, gql } = require('apollo-server');

Tworzenie schematu

Utwórzmy schemat. Musimy stworzyć dwa rodzaje:

  1. Typ zapytania z zapytaniem welcomeMessage
  2. Typ Message jest obiektem reprezentującym naszą wiadomość. Ma tylko jedno pole: tekst, które nie może być puste.

Umieść ten kod w pliku:

const typeDefs = gql`
  type Query {
    welcomeMessage: Message!
  }
  
  type Message {
    text: String!
  }
`;
10

Utwórz resolver

Nadszedł czas, aby utworzyć funkcję resolver dla zapytania welcomeMessage. W rzeczywistych projektach resolwery komunikują się z bazami danych lub innymi danymi i zbierają dane. W naszym trywialnym przykładzie chcemy zwrócić zakodowany ciąg znaków.

Proszę bardzo:

const resolvers = {
    Query: {
        welcomeMessage: () => {
            return {
                text: 'Hello World',
            };
        },
    }
}

Inicjalizacja serwera

Ostatnią rzeczą jest utworzenie instancji serwera:

const server = new ApolloServer({
    typeDefs,
    resolvers,
});

server.listen().then(({ url }) => {
    console.log(`🚀 Server ready at ${url}`);
});

Możesz uruchomić ten serwer, wpisując node ./src/index.js w konsoli.

Teraz możesz zobaczyć coś takiego:

Pobieranie GraphQL API za pomocą Apollo Studio

Podsumowanie

Mam nadzieję, że spodobała Ci się nasza krótka wycieczka po zapytaniach GraphQL. Podsumowując:

  • GraphQL posiada dwa podstawowe typy operacji: zapytania i mutacje
  • zapytania odczytują dane. Mutacje zapisują dane
  • Istnieje kilka sposobów korzystania lub sprawdzania GraphQL API, takich jak place zabaw i rozszerzenia przeglądarki.
  • zapytanie graphQL może być anonimowe lub może mieć nazwę
  • można przekazywać zmienne do zapytania
  • zmienna zapytania może mieć wartość domyślną
  • każde zwrócone pole może mieć zagnieżdżony obiekt z innymi danymi
  • Istnieją predefiniowane dyrektywy, takie jak @include i @skip, a także można pisać własne dyrektywy po stronie serwera.
  • Do stworzenia serwera graphQL można użyć serwerów Node i Apollo.
  • Oczywiście można nawet użyć PHP do napisania serwera apollo, ale kto chce pisać kod w PHP?

Te podstawowe informacje powinny pomóc w zrozumieniu podstaw zapytań graphQL.

Udostępnij post:

Możesz także polubić

Kariera w branży technologicznej: Jak rozwijać swoje umiejętności

Jesteś programistą i chciałbyś się rozwijać? W internecie znajdziesz pełno materiałów o tym, jak to zrobić. Pomimo tego nie uciekaj — mam coś, co Cię zaciekawi. Czy wiesz, że Adam Małysz — legendarny polski skoczek, zanim został mistrzem latania, to był dekarzem? Nie śmiem się porównywać z Panem Adamem, natomiast są dwie rzeczy, które nas łączą.

Ja też byłem dekarzem i też udało mi się przebranżowić. Może nie w tak spektakularny sposób, ale jednak. W tym artykule podzielę się z Tobą moim osobistym doświadczeniem, które zdobyłem na drodze od dekarza przez programistę do tech leada i dam Ci wskazówki, które będziesz mógł zastosować, aby się rozwijać i awansować, a może nawet zmienić diametralnie swoją karierę.

Czytaj więcej
AHA stack przywróćmy prostotę frontendu

AHA! Przywróćmy prostotę Frontendu

Czy zastanawiałeś się, dlaczego w dzisiejszych czasach, gdy mamy dostęp do najnowszych technologii i rozwiązań, projekty IT nadal kończą się fiaskiem? Czy nie uważasz, że w wielu przypadkach zamiast upraszczać to komplikujemy sobie życie i pracę? Czasami mniej znaczy więcej, zwłaszcza w świecie frontendu! Czytaj dalej i dowiedz się czym jest AHA stack i jak robić frontend prościej.

Czytaj więcej