Как создать GraphQL API?

Что такое GraphQL Cover

В последние годы GraphQL стал популярным выбором для создания сложных API. Это связано с тем, что он устраняет некоторые ограничения традиционных REST API и делает ваш API более гибким и эффективным.

В этой статье мы расскажем о GraphQL, его преимуществах и недостатках, ключевой терминологии GraphQL, а также сравним GraphQL API с REST API. Кроме того, мы научим вас создавать собственный GraphQL API на Back4app и подключаться к нему с помощью фронтенда Next.js.

Введение в GraphQL

GraphQL – это язык запросов и серверная среда выполнения для разработки интерфейсов прикладного программирования (API). С помощью GraphQL клиенты могут указать, какие именно данные им нужны от API, а не полагаться на то, что бэкэнд предоставит фиксированный набор данных.

GraphQL – это современный и эффективный подход к созданию быстрых и гибких API. Он имеет встроенную систему типов и основан на сильно типизированной схеме, определяющей данные, доступные через API. Он поддерживает обновления и подписки в режиме реального времени и позволяет разработчикам получать данные из нескольких источников. Кроме того, она облегчает эволюцию API, предоставляя разработчикам возможность устаревать поля без ущерба для существующих запросов и мутаций.

GraphQL можно использовать с самого начала проекта или интегрировать в существующий API. Некоторые компании также сочетают его с REST, а затем переходят на него шаг за шагом.

Он был разработан внутри компании Facebook в 2012 году, а затем выложен в открытый доступ в 2015 году. GraphQL приобрел популярность с ростом одностраничных приложений (SPA) и мобильных приложений. С момента его выпуска он был принят многими технологическими гигантами, такими как GitHub, Airbnb, Pinterest и Shopify.

GraphQL против REST

GraphQL и REST – два популярных подхода к созданию веб-интерфейсов.

REST (Representational State Transfer) – это архитектурный стиль программного обеспечения, который описывает структуру веба. Он был представлен в 2000 году и уже более десяти лет является стандартом де-факто для создания веб-интерфейсов. Для работы с ресурсами используются такие методы HTTP, как GET, POST, PUT, PATCH и DELETE. Каждый ресурс размещается в своей конечной точке (см. изображение ниже), и каждый раз, когда мы запрашиваем ресурс, возвращается весь “набор данных”.

Такая архитектура порождает две проблемы. Первая – это недостаточная выборка (получение слишком малого количества данных) и избыточная выборка (получение слишком большого количества данных). Кроме того, REST API не позволяют нам подписываться на изменения данных.

Именно здесь на помощь приходит GraphQL. GraphQL имеет одну конечную точку и позволяет запрашивать данные из нескольких источников одним запросом. Он позволяет точно определить, какие данные нам нужны. Кроме того, GraphQL позволяет нам подписываться на изменения данных без опроса сервера. Это делает наш API более предсказуемым и самодокументированным.

В конечном итоге выбор между GraphQL и REST будет зависеть от конкретных требований вашего проекта. Несмотря на то что GraphQL очень хорош, для простых проектов он может оказаться слишком сложным.

REST API против GraphQL API

Общие термины GraphQL

Давайте рассмотрим некоторые общие термины, с которыми вы можете столкнуться при работе с GraphQL.

Тип

GraphQL имеет систему типов и является сильно типизированным. Он поставляется с некоторыми встроенными скалярными типами, такими как Int, Float, String и Boolean, но также позволяет определять пользовательские типы.

Пользовательский тип можно определить следующим образом:

type User {
    username: String!
    password: String!
    friends: [User!]
}

Схема

Схема – это описание данных, доступных через GraphQL API. Она включает в себя типы объектов, их поля и связанные с ними типы данных, отношения, запросы, мутации и многое другое. Обычно схема определяется с помощью языка определения схем (SDL).

Пример схемы

Резольвер

Резольвер – это функция, которая получает данные для определенного поля в запросе GraphQL. Функции резольвера отвечают за получение данных из источника данных и возвращают их в ожидаемом формате.

Запрос

Запрос – это запрос на получение данных из GraphQL API только для чтения. Запросы можно сравнить с GET-запросами в REST API.

Пример:

query GetUser {
    user(id: "Wfx8o2AZrE") {
        id
        username
        fullName
    }
}

Этот запрос возвращает список всех пользователей.

Мутация

Мутация – это запрос на манипуляцию данными в GraphQL API. Мутации можно сравнить с запросами POST/PUT/PATCH/DELETE в REST API. Мутации также могут определять, какие данные будут возвращены.

Пример:

mutation CreateAuthor {
  createAuthor(input: {fields: {firstName: "William", lastName: "Shakespeare"}}) {
    author {
      id
      createdAt
    }
  }
}

Эта мутация создает нового автора и возвращает его id и createdAt.

Подписка

Подписка – это запрос на получение обновлений от GraphQL API в режиме реального времени. Подписки позволяют клиентам получать обновления, как только они становятся доступны, без опроса сервера.

Пример:

subscription OnPostCreate($postID: ID!) {
  userAdded(postID: $postID) {
    id
    user
    content
  }
}

Эта подписка вызывается при создании нового сообщения.

Как работает GraphQL?

Чтобы реализовать GraphQL API, необходимо выполнить следующие действия:

  1. Опишите данные с помощью схемы
  2. Подключение резольверов к источникам данных
  3. Пишите запросы и мутации
  4. Получайте предсказуемые результаты

При использовании Back4app или аналогичного сервиса большая часть этой работы будет абстрагирована. По мере создания моделей баз данных Back4app будет автоматически генерировать схему GraphQL и документацию. Подробнее об этом в практической части учебника.

В чем преимущества GraphQL?

GraphQL прост в освоении, пользователи могут объединять данные из разных источников, и это современный язык для вашего API.

Схема

GraphQL API основан на сильно типизированной схеме. Это позволяет обнаруживать ошибки типов и баги во время компиляции, а не во время выполнения. Кроме того, API GraphQL интроспективны, то есть они могут предоставлять информацию о себе, не полагаясь на внешнюю документацию.

Гибкий и эффективный сбор данных

API GraphQL чрезвычайно гибки, поскольку позволяют клиентам указывать именно то, что им нужно. Это решает проблему недостаточной и избыточной выборки и уменьшает количество запросов к API. Меньшее количество API-запросов приводит к повышению производительности.

Обновления API

С помощью GraphQL можно легко интегрировать новые поля и типы, не затрагивая текущие запросы. Устаревшие и неактуальные поля также могут быть скрыты от инструментов. API GraphQL предоставляют приложениям постоянный доступ к новым функциям и стимулируют разработку более чистого и устойчивого серверного кода.

Единый источник истины

Схема GraphQL представляет собой единый источник истины в приложении GraphQL. Она предлагает организации простой способ управления всем API.

Расширения GraphQL

GraphQL поддерживается огромным сообществом разработчиков GraphQL и поставляется с множеством расширений с открытым исходным кодом. Расширения упрощают некоторые общие задачи API, такие как пагинация, кэширование, мониторинг производительности и так далее.

Каковы недостатки GraphQL?

Сложность

GraphQL перекладывает большую часть работы по запросу данных на серверную сторону, что делает бэкенды более сложными. Кроме того, язык запросов и определения схем могут потребовать более тщательного планирования и обслуживания.

Кривая обучения

GraphQL имеет более сложную кривую обучения, чем REST. Кроме того, разработчики GraphQL обычно дороже и их труднее найти, чем разработчиков REST.

Отсутствие стандартизации

Одним из основных критических замечаний в адрес GraphQL является отсутствие стандартизации в его реализации. REST API имеют устоявшийся набор принципов и лучших практик, в то время как документация по GraphQL содержит лишь общие советы по реализации. Это может привести к несоответствиям и путанице в том, как разрабатываются и используются API GraphQL.

Безопасность

Преимущество GraphQL в том, что клиенты могут запрашивать именно то, что им нужно, но, с другой стороны, это может быть потенциальным риском для безопасности. Важно правильно проверять и санировать пользовательский ввод, чтобы предотвратить выполнение вредоносных запросов.

Как создать GraphQL API?

В этом разделе статьи мы рассмотрим, как создать GraphQL API с помощью Back4app и подключиться к нему из фронтенда Next.js.

Пререквизиты

  • Опыт работы с JavaScript ES6
  • Опыт работы с React и Next.js
  • Базовое понимание GraphQL

Что такое Back4app?

Back4app – это исключительное решение Backend as a Service (BaaS), которое работает на базе программного обеспечения с открытым исходным кодом. Платформа предоставляет широкий спектр возможностей, которые позволяют пользователям легче и быстрее разрабатывать веб- и мобильные приложения. Это позволяет компаниям сосредоточиться на бизнес-логике, не заботясь о бэкенде или базовой инфраструктуре.

Back4app поставляется с простой в использовании приборной панелью, оснащенной множеством функций, и интерфейсом командной строки (CLI). Кроме того, компания предоставляет комплекты для разработки программного обеспечения (SDK) для различных популярных инструментов, таких как Node.js, Flutter, React Native, Android, Angular, iOS и других.

Back4app придерживается простой модели ценообразования, которая может удовлетворить потребности любого приложения. Они также предлагают бесплатный тарифный план (не требуется кредитная карта), который отлично подходит для тестирования и создания прототипов.

Хотите узнать больше о Back4app? Ознакомьтесь с разделом Зачем использовать Back4app?

Введение в проект

Мы создадим простое веб-приложение TODO. Приложение будет состоять из двух частей: бэкенда и фронтенда. Бэкенд будет работать на основе GraphQL API и развернут на Back4app. Фронтенд, с другой стороны, будет написан на TypeScript с использованием фреймворка Next.js. Для подключения фронтенда к бэкенду мы будем использовать Apollo Client.

Итоговое приложение будет выглядеть следующим образом:

Предварительный просмотр проекта back4app-graphql

Бэкэнд

Создать приложение Back4app

Чтобы выполнить следующие шаги, вам необходимо иметь учетную запись Back4app. Если он у вас уже есть, пожалуйста, войдите в него. В противном случае, не стесняйтесь регистрироваться для получения бесплатной учетной записи.

Чтобы использовать Back4app, первым шагом будет создание приложения. После того как вы войдете в свою панель, вы сможете просмотреть список текущих приложений. Чтобы создать новое приложение, нажмите на кнопку “Создать новое приложение”.

Back4app Создание приложений

Поскольку мы создаем GraphQL API, выберите опцию “Backend as a Service” и укажите уникальное имя для вашего приложения. Кроме того, выберите тип базы данных “NoSQL”.

Терпеливо ждите, пока Back4app настроит все необходимое для вашего приложения, включая базу данных, уровень приложений, масштабирование, резервное копирование и безопасность.

После завершения настройки вы попадете на приборную панель вашего приложения.

Создано приложение Back4app

Определение моделей баз данных

Поскольку мы создаем простое приложение TODO, нам понадобится только одна модель базы данных.

Чтобы начать, перейдите на приборную панель Back4app и найдите опцию “База данных” на боковой панели. Оттуда выберите “Создать класс” и дайте ему имя “Task”. Убедитесь, что выбрано “Public Read and Write Enabled”, а затем нажмите “Create class & add columns”.

Back4app Определите модель

Включите последующие столбцы:

+-----------+------------------+---------------+----------+
| Data type | Name             | Default value | Required |
+-----------+------------------+---------------+----------+
| String    | name             | <leave blank> | yes      |
+-----------+------------------+---------------+----------+
| String    | description      | <leave blank> | no       |
+-----------+------------------+---------------+----------+
| Boolean   | isDone           | false         | no       |
+-----------+------------------+---------------+----------+

После создания модели базы данных вы заметите, что четыре столбца базы данных были добавлены автоматически:

  1. objectId – первичный ключ вашего объекта
  2. updatedAt – временная метка последнего обновления
  3. createdAt – временная метка создания
  4. ACL определяет “список управления доступом”.

Запомните их, поскольку они понадобятся нам позже в учебнике при работе с GraphQL-запросами и мутациями.

Чтобы познакомиться с панелью Back4app, попробуйте добавить два примера задач, например:

+-----------------+----------------------------------------+--------+
| name            | description                            | isDone |
+-----------------+----------------------------------------+--------+
| GraphQL backend | Create a GraphQL backend via Back4app. | false  |
+-----------------+----------------------------------------+--------+
| Learn GraphQL   | Learn the basics of GraphQL.           | true   |
+-----------------+----------------------------------------+--------+

Консоль API GraphQL

Консоль API GraphQL позволяет тестировать запросы и мутации GraphQL перед их реализацией в коде. Чтобы получить доступ к консоли, выберите “API” на боковой панели, а затем “Консоль > GraphQL”.

Back4app GraphQL Console

Консоль очень проста в использовании. В левой части мы можем вводить пользовательские запросы и мутации, а результаты отображаются справа.

Чтобы проверить, все ли работает, выполните следующий запрос:

query CheckHealth {
    health
}

Вы должны получить следующий ответ в формате JSON:

{
  "data": {
    "health": true
  }
}

Один из плюсов Back4app в том, что он основан на Parse. Когда мы создали нашу модель базы данных, Parse автоматически настроил для нас GraphQL. Это включает в себя генерацию схемы GraphQL, документации и так далее.

Попробуем перечислить задачи и их детали из базы данных:

query GetTasks {
  tasks {
    count
    edges {
      node {
        id
        name
        description
        isDone
      }
    }
  }
}

Вы должны получить аналогичный ответ:

{
  "data": {
    "tasks": {
      "count": 2,
      "edges": [
        {
          "node": {
            "id": "VGFzazpXQkJzSkRtV2xU",
            "name": "GraphQL backend",
            "description": "Create a GraphQL backend via Back4app.",
            "isDone": false
          }
        },
        {
          "node": {
            "id": "VGFzazpnM2lhNzdwUXBp",
            "name": "Learn GraphQL",
            "description": "Learn the basics of GraphQL.",
            "isDone": true
          }
        }
      ]
    }
  }
}

Получение конкретного объекта, создание объектов, их обновление и т. д. выполняется аналогично. Я не буду вдаваться в подробности сейчас, поскольку объясню эти запросы и мутации позже в учебнике. Кроме того, в документации Back4app эти темы хорошо освещены:

  1. Создание объекта
  2. Получение объекта
  3. Поиск объектов
  4. Обновление объекта
  5. Удаление объекта
  6. Аутентификация

Это все, что касается внутренней части. В следующем разделе мы начнем работать над фронтендом.

Frontend

Создать следующее приложение

Самый простой способ загрузить проект Next.js – использовать утилиту create-next-app. Откройте терминал и выполните следующую команду:

$ yarn create next-app

√ What is your project named? ... back4app-graphql
√ Would you like to use TypeScript with this project? ... No
√ Would you like to use ESLint with this project? ... Yes
√ Would you like to use the `src/` directory with this project? ... No
√ Would you like to use the experimental `app/` directory with this project? ... No
√ What import alias would you like configured? ... @/*

Successfully created a Next.js app.

Затем запустите сервер разработки:

$ yarn dev

Перейдите по адресу http://localhost:3000, и вы увидите целевую страницу Next.js, созданную по умолчанию.

NextJS Default Landing Page

ChakraUI

Чтобы ускорить и упростить процесс создания UI/UX, мы будем использовать ChakraUI. Chakra UI – это простая, модульная и доступная библиотека компонентов, которая предоставляет вам все необходимое для создания приложений на React.

Если у вас возникнут проблемы, обратитесь к разделу ChakraUI: Начало работы с Next.js.

Чтобы установить его, выполните следующие действия:

yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion

Далее перейдите к файлу _pages/app.tsx и оберните свое приложение с помощью ChakraProvider следующим образом:

// pages/_app.tsx

import "../styles/globals.css";
import type {AppProps} from "next/app";
import {ChakraProvider} from "@chakra-ui/react";

export const theme = extendTheme({});

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider theme={theme}>
      <Component {...pageProps} />
    </ChakraProvider>
  );
}

export default MyApp;

Не забудьте импортировать ChakraProvider:

import {ChakraProvider} from "@chakra-ui/provider";

Чтобы избежать случайных вспышек цвета, убедитесь, что скрипт цветового режима загружен до контента. Для этого вы можете использовать _document.js следующим образом:

// pages/_document.tsx

import {ColorModeScript} from "@chakra-ui/react";
import { Html, Head, Main, NextScript } from "next/document";
import {theme} from "@/pages/_app";

export default function Document() {
  return (
    <Html lang='en'>
      <Head />
      <body>
        <ColorModeScript initialColorMode={theme.config.initialColorMode} />
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

Отлично, вы успешно установили ChakraUI.

Пользовательский интерфейс

Переходим к созданию пользовательского интерфейса. Наше веб-приложение будет состоять из двух следующих страниц:

  1. / отображает список заданий
  2. создать/ отображает форму для создания заданий

Начните с замены файла pages/index.tsx следующим содержимым:

// pages/index.tsx

import type {NextPage} from "next";
import {
    Button, Card, CardBody, Container,
    Heading, HStack, Stack, Text, VStack
} from "@chakra-ui/react";
import Link from "next/link";

let data = {
  "tasks": {
    "count": 2,
    "edges": [
      {
        "node": {
          "id": "VGFzazpXQkJzSkRtV2xU",
          "name": "GraphQL backend",
          "description": "Create a GraphQL backend via Back4app.",
          "isDone": false
        }
      },
      {
        "node": {
          "id": "VGFzazpnM2lhNzdwUXBp",
          "name": "Learn GraphQL",
          "description": "Learn the basics of GraphQL.",
          "isDone": true
        }
      }
    ]
  }
};

const ListPage: NextPage = () => {

  const handleMarkAsDone = async (id: string, isDone: boolean) => {
    console.log("TODO: mark task as done and refetch");
  };

  const handleDelete = async (id: string) => {
    console.log("TODO: delete task and refetch");
  };

  return (
    <>
      <Container maxWidth="container.lg">
        <HStack w="fill" justifyContent="space-between" mt={8} mb={4}>
          <Heading as="h1" size="lg">back4app-graphql</Heading>
          <Link href="/create">
            <Button size="sm" colorScheme="blue">
              Create task
            </Button>
          </Link>
        </HStack>
        <VStack spacing={4}>
          {data.tasks.edges.map((edge) => {
            let task = edge.node;
            return (
              <Card key={task.id} w="100%">
                <CardBody>
                  <Stack direction="column">
                    <Heading as="h2" size="md">
                      {task.isDone ? "✔️" : "❌"}{" "}
                      {task.name}
                    </Heading>
                    <Text>
                      {task.description}
                    </Text>
                    <Stack direction="row" pt={2}>
                      <Button size="sm" colorScheme="blue" onClick={() => handleMarkAsDone(task.id, task.isDone)}>
                        Toggle done
                      </Button>
                      <Button size="sm" colorScheme="red" onClick={() => handleDelete(task.id)}>
                        Delete
                      </Button>
                    </Stack>
                  </Stack>
                </CardBody>
              </Card>
            );
          })}
        </VStack>
      </Container>
    </>
  );
};

export default ListPage;
  1. Для разработки пользовательского интерфейса мы использовали ChakraUI.
  2. В настоящее время задачи загружаются из статического массива с именем data.
  3. Позже мы будем использовать handleMarkAsDone() и handleDelete() для отправки запросов GraphQL API.

Затем создайте файл create.tsx в папке pages со следующим содержимым:

// pages/create.tsx

import type {NextPage} from "next";
import {
  Button, Card, CardBody, CardHeader, Container, FormControl,
  FormLabel, Heading, HStack, Input, Stack, Switch, Text
} from "@chakra-ui/react";
import Link from "next/link";
import {useState} from "react";
import {useRouter} from "next/router";

const CreatePage: NextPage = () => {
  const router = useRouter();

  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [isDone, setIsDone] = useState(false);

  const [formError, setFormError] = useState("");

  const handleSubmit = (event) => {
    event.preventDefault();

    if (!name || !description) {
      setFormError("Please enter the title and the description.");
      return;
    }

    console.log("TODO: call the GraphQL API and redirect");
  };

  return (
    <>
      <Container maxWidth="container.lg">
        <HStack w="fill" justifyContent="space-between" mt={8} mb={4}>
          <Heading as="h1" size="lg">back4app-graphql</Heading>
          <Link href="/">
            <Button size="sm" colorScheme="blue">
              View list
            </Button>
          </Link>
        </HStack>
        <Card>
          <CardHeader>
            <Stack direction="column">
              <Heading as="h2" size="md">Create task</Heading>
              <Text>
                Fill out the form and press &quot;Create&quot; to create a new task.
              </Text>
            </Stack>
          </CardHeader>
          <CardBody>
            <form onSubmit={handleSubmit}>
              <Stack direction="column">
                {formError && <Text color="red.500" fontWeight="bold">{formError}</Text>}
                <FormControl>
                  <FormLabel>Name</FormLabel>
                  <Input type="text" value={name} onChange={(event) => setName(event.target.value)}/>
                </FormControl>
                <FormControl>
                  <FormLabel>Description</FormLabel>
                  <Input type="text" value={description} onChange={(event) => setDescription(event.target.value)}/>
                </FormControl>
                <FormControl display="flex" alignItems="center">
                  <FormLabel mb="0">
                    Is done?
                  </FormLabel>
                  <Switch isChecked={isDone} onChange={() => setIsDone(!isDone)}/>
                </FormControl>
                <Button size="sm" colorScheme="blue" type="submit">Create task</Button>
              </Stack>
            </form>
          </CardBody>
        </Card>
      </Container>
    </>
  );
};

export default CreatePage;
  1. Для создания пользовательского интерфейса мы снова использовали компоненты ChakraUI.
  2. Мы создали управляемую React-форму для создания задач.
  3. Функция handleSubmit() будет использована позже для отправки запроса API.

Перезапустите свой веб-сервер и зайдите в веб-приложение по адресу http://localhost:3000. Вы должны увидеть две жестко закодированные задачи. Далее нажмите на кнопку “Создать задачу”, чтобы увидеть форму создания задачи.

Back4app GraphQL Создать задачу

Клиент GraphQL

Чтобы подключиться к GraphQL API из фронтенда, сначала нужно установить GraphQL Client. Я предлагаю вам выбрать Apollo Client, поскольку он прост в настройке, не требует вмешательства и не требует большого количества шаблонов.

Начните с установки @apollo/client и graphql:

$ yarn add @apollo/client graphql

Для инициализации клиента вам потребуется предоставить свои учетные данные Back4app API. Самый простой способ получить учетные данные – перейти в консоль GraphQL и обратить внимание на заголовки.

Учетные данные Back4app GraphQL

Поскольку вы не хотите раскрывать ключи API в исходном коде, создайте в корне проекта файл .env.local со следующим содержимым:

# .env.local

NEXT_PUBLIC_PARSE_APPLICATION_ID=<YOUR_PARSE_APP_ID>
NEXT_PUBLIC_PARSE_MASTER_KEY=<YOUR_PARSE_MASTER_KEY>
NEXT_PUBLIC_PARSE_CLIENT_KEY=<YOUR_PARSE_CLIENT_KEY>

Далее перейдите в файл pages/_app.tsx и инициализируйте клиент Apollo, а затем оберните ваше приложение с помощью ApolloProvider следующим образом:

// pages/_app.tsx

// ...
import {ApolloClient, ApolloProvider, InMemoryCache} from "@apollo/client";

const client = new ApolloClient({
  uri: "https://parseapi.back4app.com/graphql",
  headers: {
    "X-Parse-Application-Id": process.env.NEXT_PUBLIC_PARSE_APPLICATION_ID,
    "X-Parse-Master-Key": process.env.NEXT_PUBLIC_PARSE_MASTER_KEY,
    "X-Parse-Client-Key": process.env.NEXT_PUBLIC_PARSE_CLIENT_KEY,
  },
  cache: new InMemoryCache(),
});

function MyApp({ Component, pageProps }: AppProps) {
  return (
    <ChakraProvider theme={theme}>
      <ApolloProvider client={client}>
        <Component {...pageProps} />
      </ApolloProvider>
    </ChakraProvider>
  );
}

Подождите, пока фронтенд перекомпилируется, затем зайдите в веб-приложение и проверьте консоль на наличие ошибок. Отсутствие ошибок означает, что подключение прошло успешно.

Запросы и мутации GraphQL

Последнее, что вам нужно сделать, это определить ваши GraphQL-запросы и мутации, а затем вызвать их из вашего кода React.

Чтобы включить помощь с кодом GraphQL в вашей IDE, перейдите в Back4app GraphQL Console, выберите “Schema” на боковой панели и загрузите его в формате SDL. Затем создайте новый файл с именем schema.graphql в корне проекта и вставьте в него содержимое SDL.

Сначала перейдите в файл pages/index.tsx и добавьте следующие запросы после импорта:

// pages/index.tsx

const GET_TASKS = gql`
  query GetTasks {
    tasks {
      count
      edges {
        node {
          id
          name
          description
          isDone
        }
      }
    }
  }
`;

const UPDATE_TASK = gql`
  mutation UpdateTask($id: ID!, $isDone: Boolean!) {
    updateTask(input: { id: $id, fields: { isDone: $isDone } }) {
      task {
        isDone
        updatedAt
      }
    }
  }
`;

const DELETE_TASK = gql`
  mutation DeleteTask($id: ID!) {
    deleteTask(input: { id: $id }) {
      task {
        id
      }
    }
  }
`;

Эти три запроса не требуют пояснений. Первый возвращает список всех задач, второй обновляет свойство isDone конкретной задачи, а третий удаляет конкретную задачу.

Далее измените верхнюю часть ListPage следующим образом:

// pages_index.tsx

// ...

const ListPage: NextPage = () => {

  const {loading, error, data, refetch} = useQuery(GET_TASKS);
  const [deleteTask] = useMutation(DELETE_TASK);
  const [updateTask] = useMutation(UPDATE_TASK);

const handleMarkAsDone = async (id: string, isDone: boolean) => {
    try {
      const updateTaskResponse = await updateTask({
        variables: {id: id, isDone: !isDone}
      });
      console.debug(updateTaskResponse);
      refetch();
    } catch (error) {
      console.error(error);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      const deleteTaskResponse = await deleteTask({
        variables: {id: id},
      });
      console.debug(deleteTaskResponse);
      refetch();
    } catch (error) {
      console.error(error);
    }
  };

  if (error) return <p>Oops, something went wrong.</p>;
  if (loading) return <Spinner/>;

  // ...
};

export default ListPage;
  1. Мы использовали функцию useQuery() для выполнения запроса GET_TASKS и сохранения результата.
  2. Мы использовали функцию useMutation() для определения мутаций GraphQL.
  3. Мы обновили handleMarkAsDone() и handleDelete(), чтобы использовать крючки мутации.

Двигаясь дальше, измените pages/create.tsx аналогичным образом:

const CREATE_TASK = gql`
  mutation CreateTask($name: String!, $description: String, $isDone: Boolean!) {
    createTask(
      input: {
        fields: { name: $name, description: $description, isDone: $isDone }
      }
    ) {
      task {
        id
      }
    }
  }
`;

const CreatePage: NextPage = () => {

  // ...

  const [createTask] = useMutation(CREATE_TASK);

  const handleSubmit = (event) => {
    event.preventDefault();

    if (!name || !description) {
      setFormError("Please enter the title and the description.");
      return;
    }

    createTask({
      variables: {name: name, description: description, isDone: isDone}
    }).then(response => {
      router.push("/");
    });
  };

  // ...
};

export default CreatePage;

Не забывайте об импорте:

import {gql, useMutation, useQuery} from "@apollo/client";

Отлично, вот и все!

Перезапустите сервер разработки и зайдите в веб-приложение. Проверьте, загружаются ли задачи из базы данных, попробуйте создать новую задачу, пометить ее как выполненную и удалить.

Заключение

В заключение можно сказать, что GraphQL – это хороший выбор для создания сложных API благодаря гибким возможностям запросов и эффективному получению данных. Несмотря на множество преимуществ по сравнению с традиционными REST API, есть и недостатки, которые следует учитывать при запуске проекта.

В этой статье мы обсудили преимущества и недостатки GraphQL, сравнили его с REST API и ввели некоторые ключевые термины GraphQL. Теперь вы должны быть в состоянии создать свой собственный простой GraphQL API на Back4app и подключиться к нему с помощью JavaScript-фронтенда.

Вы можете взять финальный исходный код из репозитория GitHub.

ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ

Что такое GraphQL?

GraphQL — это язык запросов и серверное окружение для разработки мощных и гибких API.

В чем основные отличия между REST и GraphQL?

REST — это стандартизированный и простой подход к созданию веб-сервисов, тогда как GraphQL предлагает более гибкие возможности запросов и устраняет недостаточную или избыточную выборку данных.

Какие термины чаще всего используются в GraphQL?

– Схема (Schema) — описание данных, доступных через GraphQL API.
– Резолвер (Resolver) — функция, извлекающая данные для конкретного поля в запросе GraphQL.
– Запрос (Query) — запрос только для чтения данных из GraphQL API.
– Мутация (Mutation) — запрос на изменение данных в GraphQL API.
– Подписка (Subscription) — запрос на получение обновлений в реальном времени из GraphQL API.

Как создать GraphQL API?

1. Создайте бесплатный аккаунт на Back4app.
2. Спроектируйте модели базы данных.
3. Напишите запросы и мутации через консоль Back4app GraphQL API.
4. Установите клиент GraphQL (например, Apollo или Relay) в ваш frontend-проект.
5. Инициализируйте клиент и подключитесь к GraphQL API.


Leave a reply

Your email address will not be published.