Как использовать GraphQL для базы данных Firebase Realtime Database с помощью StepZen

База данных Firebase Realtime Database — это база данных NoSQL, размещенная в облаке. Данные синхронизируются в режиме реального времени с каждым клиентом на всех платформах (Web, iOS и Android). Данные хранятся в формате JSON и предоставляются всем вашим клиентам при создании кросс-платформенных приложений. Это гарантирует, что все ваши клиенты всегда будут иметь самые свежие данные, даже в режиме офлайн.

Вы можете найти полный код этой статьи в нашем репозитории примеров на Github или посмотреть видео-обзор на нашем канале Youtube.

Firebase — это облачная платформа от Google, которая позволяет быстро создавать веб- и мобильные приложения. Она предлагает услуги аутентификации, хранения данных, мониторинга, протоколирования и развертывания. База данных реального времени — одна из услуг, предлагаемых разработчикам. Вы можете получить доступ к данным из базы данных Firebase Realtime Database с помощью REST API. Но у него нет GraphQL API, который мы создадим с помощью StepZen.

Настройка базы данных Firebase Realtime Database

Первый шаг к использованию сервиса Firebase — это создание бесплатной учетной записи в консоли Firebase, если вы этого еще не сделали. Вы получите совершенно новое приложение Firebase с уникальным URL, который заканчивается на firebaseio.com. Этот URL используется для хранения и синхронизации данных в базе данных приложения и аутентификации ваших пользователей.

В консоли Firebase вам нужно создать новый проект; назовем его «StepZen demo». В процессе установки вам будет задано несколько вопросов о конфигурации, которые вы можете проигнорировать в рамках данного демо. Через несколько минут ваш новый проект Firebase будет готов, и вы можете продолжить работу, добавив базу данных Realtime Database с помощью навигации в левой части страницы.

Когда вы нажмете кнопку «Создать базу данных», вам нужно выбрать регион, в котором вы хотите создать базу данных. Например, Соединенные Штаты, Европа или Азия. Также необходимо настроить параметры безопасности для базы данных Realtime Database. Сначала необходимо включить «тестовый режим», чтобы облегчить создание и чтение наших первых данных:

При нажатии кнопки «Включить» ваша база данных создается в выбранном вами регионе. В зависимости от региона вашей базы данных URL будет либо YOUR_FIREBASE_PROJECT_ID.firebaseio.com (для баз данных, расположенных в us-central1), либо YOUR_FIREBASE_PROJECT_ID.REGION.firebasedatabase.app для баз данных во всех остальных местах.

Последним шагом является добавление данных в базу данных, что можно сделать из консоли Firebase или через REST API. Чтобы внести начальные данные в базу данных, мы будем использовать консоль Firebase для загрузки JSON-файла init.json, который вы можете найти в репозитории Github для этого поста здесь. Нажав на три точки в правой части экрана, вы можете выбрать «Import JSON».

После загрузки данных вы можете увидеть в консоли Firebase, что в базе данных есть клиенты и заказы. Вот и все. Ваша база данных Firebase Realtime готова к работе. На следующем этапе мы создадим схему StepZen GraphQL.

Создание схемы GraphQL

Вы можете получить данные из базы данных Firebase Realtime с помощью их REST API. Пример запроса curl для получения одного клиента:

`curl 'https://YOUR_FIREBASE_PROJECT_ID.firebaseio.com/customers/-N6rOmxa7vOOTpZZSllL.json'`

Войти в полноэкранный режим Выйти из полноэкранного режима

С помощью StepZen мы можем использовать ту же команду curl для создания GraphQL API, который получает те же данные. Сначала необходимо установить StepZen CLI, используя:

`npm i -g stepzen`

Войти в полноэкранный режим Выйти из полноэкранного режима

И запустить команду для преобразования Firebase REST API в GraphQL. В этой команде, как вы видите, используется начальный curl вместе с несколькими флагами для названия генерируемого запроса и типа ответа:

`stepzen import curl 'https://YOUR_FIREBASE_PROJECT_ID.firebaseio.com/customers/-N6rOmxa7vOOTpZZSllL.json' --name customer --query-name getCustomerById --query-type Customer` 

Войти в полноэкранный режим Выйти из полноэкранного режима

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

После того как StepZen CLI завершит преобразование запроса REST API в схему GraphQL, будет создано несколько файлов:

myproject
  |-- customer
      |-- index.graphql
  |-- index.graphql
  |-- stepzen.config.json
Вход в полноэкранный режим Выход из полноэкранного режима

В файле customer/index.graphql вы можете найти сгенерированную схему GraphQL.

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

`stepzen start`

Войти в полноэкранный режим Выйти из полноэкранного режима

После этого StepZen CLI развернет схему GraphQL и вернет вашу конечную точку прямо в терминале. Это выглядит как https://public***.stepzen.net/api/with-firebase/__graphql, если вы еще не зарегистрировались на StepZen. Если у вас есть учетная запись, доступны две конечные точки.

  • конечная точка localhost, которая содержит GraphiQL IDE, и
  • конечная точка production-ready, доступ к которой можно получить, предоставив ключ API StepZen.

Узнайте больше о различных конечных точках в документации.

Посетив этот публичный URL (либо localhost, либо начинающийся с https://public***), вы можете запросить конечную точку с помощью GraphiQL:

Отсюда вы можете запросить GraphQL API и проверить, как выглядят типы ответов в схеме.

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

Преобразование ответов API

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

Запрос curl для получения этого списка аналогичен запросу, который мы использовали в предыдущем разделе:

`curl 'https://YOUR_FIREBASE_PROJECT_ID.firebaseio.com/customers.json'`

Войти в полноэкранный режим Выйти из полноэкранного режима

И мы можем добавить его в схему GraphQL в customer/index.graphql вручную или выполнив еще одну команду stepzen import curl. Второй вариант имеет оговорку, поскольку импортированная схема показывает сообщение:

`Result typed as JSON since it has fields ['-N6rOmxa7vOOTpZZSllL', ...] that are invalid graphql identifiers`

Войдите в полноэкранный режим Выйти из полноэкранного режима

Ответ на запрос к REST API возвращает JSON в неподдерживаемом формате. REST API возвращает список пар ключ-значение с именами полей, представляющих ключ, а не массив.

Поэтому вам необходимо преобразовать этот объект в массив, чтобы получить список клиентов. Если вы использовали StepZen CLI для импорта конечной точки, вам нужно добавить поле transforms в запрос getCustomers. Или, если вы этого не сделали, вы можете добавить запрос getCustomers из блока кода ниже в схему в customers/index.graphql.

type Query {
  getCustomerById(id: ID!): Customer
    @rest( 
      ##
    )
  getCustomers: [JSON]
    @rest(
      endpoint: "https://YOUR_FIREBASE_PROJECT_ID.firebaseio.com/customers.json"
      transforms: [{ pathpattern: [], editor: "objectToArray" }]
    )
}
Вход в полноэкранный режим Выход из полноэкранного режима

Тип ответа для этого запроса теперь [JSON], так как StepZen CLI не смог сгенерировать тип GraphQL автоматически, поскольку GraphQL не поддерживает списки пар ключ-значение. В GraphiQL IDE для вашей конечной точки вы уже можете запросить результаты для getCustomers, но вы не сможете выбрать какие-либо поля.

Поэтому нам нужно добавить тип ответа GraphQL вручную. Тип Customer уже был создан, когда вы импортировали конечную точку Firebase REST API для получения одного клиента и добавили второй тип для преобразованной пары ключ-значение с типом CustomerList:

type Customer {
  email: String
  name: String
}

type CustomerList {
  name: ID
  value: Customer
}

type Query {
  getCustomerById(id: ID!): Customer
    @rest( 
      ##
    )
  getCustomers: [CustomerList]
    @rest(
      endpoint: "https://YOUR_FIREBASE_PROJECT_ID.firebaseio.com/customers.json"
      transforms: [{ pathpattern: [], editor: "objectToArray" }]
    )
}
Вход в полноэкранный режим Выход из полноэкранного режима

Обратите внимание, что вы также можете использовать инструмент JSON2SDL для автоматического преобразования ответа JSON в GraphQL SDL.

Когда вы вернетесь в браузер GraphiQL, вы сможете запросить список клиентов и определить поля, которые должен вернуть GraphQL API:

query {
  getCustomers {
    name
    value {
      email
      name
    }
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Несмотря на то, что ответ такой же, как и в предыдущем запросе, теперь у вас есть полный контроль над тем, какие поля будут возвращены. Если выполнить тот же запрос и убрать поле email в value, то будет возвращено только имя клиента.

В следующем разделе мы объединим информацию о заказчике с заказами, которые мы ранее импортировали в схему GraphQL.

Объединение данных в GraphQL

Помимо данных о клиентах, у нас также есть данные о заказах в Firebase Realtime Database. Чтобы объединить данные о клиентах с данными о заказах, нам нужно создать запрос для получения заказов из базы данных Firebase Realtime Database.

И снова вы можете использовать StepZen CLI для преобразования REST API в GraphQL API. Мы начнем с импорта одного заказа, чтобы тип возврата был сгенерирован автоматически:

`stepzen import curl 'https://YOUR_FIREBASE_PROJECT_ID.firebaseio.com/orders/-N6rOvLXK2t39x-Bp0UP.json' --name orders --query-name getOrderById`   

Войти в полноэкранный режим Выйти из полноэкранного режима

Это добавит новый запрос getOrderById с типом ответа Order в новую схему в order/index.graphql:

myproject
  |-- customer
      |-- index.graphql
  |-- order
      |-- index.graphql
  |-- index.graphql
  |-- stepzen.config.json
Войти в полноэкранный режим Выход из полноэкранного режима

Обе схемы связаны в index.graphql в корне проекта.

Используя запрос getOrderById, вы можете получить, например, один заказ:

{
  getOrderById(id: "-N6rOvLXK2t39x-Bp0UP") {
    carrier
    shippingCost
    customerId
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Вы можете видеть, что этот запрос также возвращает customerId. Это поле ссылается на клиентов, которые также есть в нашей базе данных. С помощью директивы @materializer вы можете использовать это значение для получения клиента и связать его с типом ответа для команды or

type Order {
  carrier: String
  createdAt: Date
  customerId: String
  customer: Customer
    @materializer(
      query: "getCustomerById"
      arguments: [{ name: "id", field: "customerId" }]
    )
  shippingCost: Int
  trackingId: String
}
Вход в полноэкранный режим Выйти из полноэкранного режима

С помощью этого дополнения вы можете получить информацию о заказчике для каждого заказа, добавив поле customer и подполя, которые вы хотите включить.

Используя @materializer, вы можете объединить любые доступные данные для запроса в вашей схеме GraphQL. Не только данные, которые поступают из той же базы данных, но и данные из внешних источников — таких как другая база данных, сторонние REST API и многое другое. В следующем разделе мы добавим логику для добавления дополнительных данных в Firebase Realtime Database.

Использование мутаций для добавления и обновления данных

Наконец, мы добавим новые данные в базу данных Firebase Realtime Database с помощью GraphQL. REST API от Firebase позволяет как вставлять, так и обновлять данные. В случае успеха запрос возвращает ID обновленного или вставленного значения.

Давайте попробуем вставить нового клиента в базу данных, добавив приведенные ниже мутацию и тип ответа в схему GraphQL в customer/index.graphql:

type Response {
  name: ID
}

type Mutation {
  insertCustomer(name: String!, email: String!): Customer
    @rest(
      endpoint: "https://$project_id.firebaseio.com/customers.json"
      method: POST
      postbody: """
      {
        "name": "{{.Get "name"}}",
        "email": "{{.Get "email"}}"
      }
      """
      configuration: "firebase_config"
    )
}
Войдите в полноэкранный режим Выйти из полноэкранного режима

Эта мутация требует параметров запроса name и string и передает их значения базовому REST API с помощью поля postbody. Синтаксис {{.Get "VARIABLE_NAME"}} используется здесь для получения значения, которое передается в GrapQL Query.

Когда вы используете следующий запрос:

mutation {
  insertCustomer(name: "Peter", email: "peter.parker@avengers.com") {
    name
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Ответ выглядит примерно так:

{
  "data": {
    "insertCustomer": {
      "name": "-N7WtNDgHYjCrED--Bq3"
    }
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Вы можете проверить, был ли добавлен клиент с именем «Peter» с помощью запроса getCustomerById и возвращаемого ID. Кроме того, вы можете найти этого нового клиента в консоли Firebase:

Вы можете не только вставлять новые данные, но и обновлять существующие. У вас есть два варианта обновления: обновление конкретных полей или замена всех данных JSON на ID. В этой статье мы будем использовать PATCH, так как PUT перезапишет данные в указанном месте, включая любые дочерние узлы.

Добавьте новую мутацию ниже в вашу схему в customer/index.graphql:

type Mutation {
  insertCustomer(name: String!, email: String!): Response
    @rest(
      ## ...
    )
  updateCustomerName(id: ID!, name: String!): Customer
    @rest(
      endpoint: "https://YOUR_PROJECT_ID.firebaseio.com/customers/$id.json"
      method: PATCH
      postbody: """
      {
        "name": "{{.Get "name"}}"
      }
      """
      configuration: "firebase_config"
    )
}
Войдите в полноэкранный режим Выйти из полноэкранного режима

Позволяет обновить имя клиента. Предположим, вы хотите изменить имя только что созданного клиента с «Peter» на «Peter Parker», вы можете сделать это следующим образом:

mutation {
  updateCustomerName(id: "-N7WtNDgHYjCrED--Bq3", name: "Peter Parker") {
    name
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Обратите внимание, что тип ответа запроса updateCustomerNameCustomer, а не Response, поскольку запросы PATCH к Firebase REST API возвращают обновленное значение.

Вот и все. Теперь вы создали схему GraphQL для базы данных Firebase Realtime Database. Когда вы захотите использовать ее в производстве, не забудьте включить аутентификацию для конечной точки REST API от Firebase.

Заключение

В этой статье мы создали GraphQL API для базы данных Firebase Realtime с использованием REST API. Этот GraphQL API позволяет вам запрашивать и изменять данные, а также создавать комбинации между различными сущностями. Вы можете найти полный код в нашем репозитории примеров на Github, а также посмотреть видео на нашем канале Youtube. Мы будем рады услышать, какой проект вы начнете создавать с помощью StepZen и Firebase. Присоединяйтесь к нашему Discord, чтобы быть в курсе новостей нашего сообщества.

Оцените статью
devanswers.ru
Добавить комментарий