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

Истоки GraphQL и зачем его использовать

GraphQL происходит от Facebook. Внутри Facebook искал способ более надежно загружать новостную ленту на мобильных устройствах.

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

Инженеры Facebook задались вопросом: «А что, если бы мы могли написать язык запросов, чтобы указывать всю необходимую информацию в одном запросе API?»

GraphQL - результат этих усилий. Он отображает отношения между объектами в вашей базе данных - создавая график. Затем они разработали язык запросов для обхода этой карты отношений. Отсюда и название GraphQL.

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

Спецификация, а не реализация

Крайне важно, что Facebook решил открыть исходный код GraphQL в качестве спецификации.

Это означает, что его можно реализовать на любом языке программирования. Пока реализация анализирует запросы, схему и т. Д. Указанным способом, она будет хорошо работать с любым другим приложением GraphQL.

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

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

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

Базовая архитектура

Для разработки функционирующего API GraphQL требуются два компонента: сервер и клиент.

  1. Сервер обрабатывает входящие запросы, анализирует эти запросы, извлекает данные, используя определенную схему, и возвращает ответ, как правило, в формате JSON.
  2. Клиент позволяет вашему приложению связываться с сервером. Хотя вы можете просто отправить простой запрос POST в конечную точку GraphQL, вы получите гораздо большую функциональность, если используете клиент GraphQL для отправки ваших запросов.

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

Как выглядит GraphQL

Наша цель для нашего API - отправить запрос GraphQL и получить ответ. Итак, давайте посмотрим, как это может выглядеть.

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

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

В GraphQL мы можем запросить полет следующим образом:

{
  flight(id: "1234") {
    origin
    destination
  }
}

Это способ GraphQL: «Назови мне пункт отправления и пункт назначения рейса 1234».

В ответ мы получим:

{
  "data": {
    "flight": {
      "origin": "DFW",
      "destination": "MKE"
    }
  }
}

Уведомление:

  • Мы получаем именно то, о чем просили - ни больше, ни меньше.
  • Мы также получаем ответ в том же формате, что и исходный запрос, который мы отправили.

Это отличительные черты GraphQL API. Это то, что делает GraphQL таким быстрым и мощным.

Однако это еще не все, что мы можем сделать. Допустим, мы хотим получить информацию о пассажире рейса:

{
  flight(id: "1234") {
    origin
    destination
    passengers {
      name
    }
  }
}

Теперь GraphQL будет просматривать график отношений между этим рейсом и его пассажирами. Взамен мы получим список пассажиров:

{
  "data": {
    "flight": {
      "origin": "DFW",
      "destination": "MKE",
      "passengers": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "R2-D2"
        }
      ]
    }
  }
}

Круто, теперь мы можем сразу увидеть всех пассажиров этого рейса с помощью одного вызова API.

Почему Хан, Люк и R2 летят внутренними рейсами - это более важный вопрос, но я слышал, что Милуоки прекрасен в это время года.

Поскольку GraphQL интерпретирует данные как график, мы можем перемещаться и в другом направлении.

{
  person(name: "Luke Skywalker") {
    passport_number
    flights {
      id
      date
      origin
      destination
   }
}

И теперь мы можем увидеть, какие рейсы забронировал Люк:

{
  "data": {
    "person": {
      "passport_number": 78120935,
      "flights": [
        {
          "id": "1234",
          "date": "2019-05-24",
          "origin": "DFW",
          "destination": "MKE"
        },
        {
          "id": "2621",
          "date": "2019-07-05",
          "origin": "MKE",
          "destination": "DFW"
        }
      ]
    }
  }
}

Ух ты, он будет в Милуоки больше месяца! Интересно, что он там делает?

Понравилось то, что вы прочитали?

Я бесплатно делюсь своим лучшим контентом со своим списком рассылки.

Присоединяйтесь к 500 другим разработчикам в моей серии писем.

Список дел

Итак, что нам нужно для создания GraphQL API?

  1. Выберите фреймворк для реализации вашего сервера GraphQL. Мы будем использовать Express.
  2. Определите схему, чтобы GraphQL знал, как маршрутизировать входящие запросы
  3. Создавайте функции распознавателя, которые обрабатывают запросы и сообщают GraphQL, что возвращать
  4. Создайте конечную точку
  5. Напишите клиентский запрос, который извлекает данные

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

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

1. Реализуйте сервер

Сначала нам нужно заложить основу для нашего API.

Вам понадобится nodejs and npm installed, чтобы следовать этому руководству с этого момента.

Давайте создадим простой сервер Express. Начните с инициализации npm:

$ npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (graphql-medium) 
version: (1.0.0) 
description: 
entry point: (index.js) 
test command: 
git repository: 
keywords: 
author: 
license: (ISC) 
About to write to /home/bennett/Repos/graphql-medium/package.json:
{
  "name": "graphql-medium",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
Is this OK? (yes)

Просто нажмите Enter, чтобы пропустить процесс инициализации. Вы можете вернуться и отредактировать свой package.json позже, если захотите.

Затем давайте установим библиотеки Express, GraphQL и Express-GraphQL:

$ npm install express express-graphql graphql
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
+ [email protected]
+ [email protected]
+ [email protected]
added 53 packages from 38 contributors and audited 151 packages in 6.169s
found 0 vulnerabilities

Теперь мы создадим новый файл с именем index.js и создадим там новый сервер barebones Express:

// index.js
const express = require('express');
const app = express();
app.get('/', function(req, res) {
  res.send('Express is working!')
});
app.listen(4000, function() {
  console.log('Listening on port 4000')
});

Попробуйте запустить node index.js. Вы должны увидеть сообщение Прослушивание порта 4000, а если вы перейдете по адресу http: // localhost: 4000 /, то увидите Экспресс работает!

2. Добавить в GraphQL и определить схему

Мы уже установили пакет GraphQL npm. А теперь давайте воспользуемся этим.

Во-первых, нам нужно импортировать необходимые строительные блоки:

const graphqlHTTP = require('express-graphql');
const { buildSchema } = require('graphql');

Далее мы воспользуемся этими строительными блоками.

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

А пока давайте просто определим схему hello world, чтобы все заработало:

let schema = buildSchema(`
  type Query {
    hello: String
  }
`);

Эта простая схема позволяет GraphQL знать, что когда кто-то отправляет запрос «привет», мы вернем строку.

Обратите внимание на эти маленькие обратные кавычки (`) там. Это означает, что мы используем литерал шаблона JavaScript. По сути, мы используем эти обратные кавычки, чтобы сообщить JavaScript, что мы собираемся писать на другом языке - языке запросов GraphQL.

3. Разрешение запросов

Итак, когда кто-то отправляет запрос для hello, мы знаем, что в конечном итоге вернем строку. Это определено в нашей схеме.

Теперь нам нужно указать GraphQL, какую именно строку он должен вернуть.

Выяснение того, какие данные возвращать на основе входящего запроса, - это задача «преобразователя» в GraphQL.

В этом примере преобразователь прост. Мы буквально собираемся вернуть строку «Hello world»

return 'Hello world!';

Однако нам нужно обернуть этот оператор return внутри функции, которая может вызываться несколько раз, каждый раз, когда кто-то делает запрос для приветствия:

function() {
  return 'Hello world!';
}

Теперь hello, возможно, не единственный тип запроса, который мы реализуем. В будущем мы могли бы также включить «конечные точки» для других функций. Итак, мы должны убедиться, что эта функция, которую мы только что создали, сопоставлена ​​с hello и сохранена в объекте вместе со всеми другими преобразователями для нашего API.

let root = {
  hello: function() {
    return 'Hello world!';
  },
}

По соглашению вызывается объект, содержащий все преобразователи root, но вы можете называть его как хотите.

4. Настройка конечной точки.

Проницательные читатели заметят, что мы импортировали graphqlHTTP на шаге 2, но еще не использовали его. Сейчас самое время.

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

В Express мы создадим новый маршрут для обслуживания API GraphQL:

app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: root,
  graphiql: true,
}));

Схема и корень указывают на переменные, которые мы определили на шагах 2 и 3.

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

Вот окончательное состояние нашего исходного кода для нашего сервера GraphQL.

5. Запустите его и напишите запрос.

Мы готовы проверить это!

  1. Запустите приложение с npm index.js
  2. Перейдите по адресу http: // localhost: 4000 / graphql

Вы должны увидеть интерфейс graphiql:

Теперь мы можем использовать этот интерфейс, чтобы убедиться, что наш API работает!

Напишем запрос. Это будет очень просто. Мы всегда заключаем наши запросы GraphQL в фигурные скобки. Затем мы указываем объект схемы, который запрашиваем, а затем все атрибуты, которые мы хотим получить.

В этом случае в нашем API пока есть только одно, что нужно получить:

{
  hello
}

Если вы нажмете кнопку отправки, вы увидите:

{
  "data": {
    "hello": "Hello world!"
  }
}

Работает!

Добавление дополнительных конечных точек

Добавить конечные точки в ваш API так же просто, как определить новые поля в вашей схеме, а затем добавить функцию преобразователя в root

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

GraphQL, FTW

GraphQL великолепен и быстро набирает обороты. В ближайшие годы он может стать повсеместной технологией для API.

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

Поделитесь своими мыслями в комментариях ниже! Я читаю каждый ответ.

О Беннетте

Я веб-разработчик, создающий вещи на Python и JavaScript.

Хотите, чтобы мой лучший контент по веб-разработке и стал лучшим программистом?

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

Присоединяйтесь к 500 другим разработчикам в моей серии писем.