Как пользоваться GraphQL API проекта St.Retrospect

Как пользоваться GraphQL API проекта St.Retrospect


Скорее всего, вы уже слышали о проекте St.Retrospect, который развивает DH Center. Если по какой-то причине вы ещё не знаете про него, то Ретроспект (так проще говорить) — это проект на стыке философии культуры, культурологии, истории и IT технологий. Целью проекта является создание интерактивного интерфейса, содержащего историко-культурологические данные о ключевых персонах и локациях, связанных с Санкт-Петербургом.

У проекта уже сейчас довольно обширная и в некотором роде уникальная база данных. В ней содержится информация о персонах, которые каким-либо образом связаны с Санкт-Петербургом, локациях (парки, дома, музеи и т.д.), а также информация о связях между конкретными персонами и локациями (например, мы можем узнать где жила та или иная историческая личность). Качество информации в нашей БД далеко от идеала (например, очень много пустых, непроработанных мест), поэтому мы сейчас очень активно работаем над её улучшением (вы, кстати, можете помочь нам, если есть желание).

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

GraphQL

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


Описание типов

Первое, с чего начинается построение GraphQL API — описание типов данных и способов их получения. Описывается это всё с помощью специального языка, называемого Schema Definition Language (SDL).

Например вот так мы определяем тип "Персона" в нашем API:

Определение типа Персона

Определение типа начинается с ключевого слова type, далее идёт название типа, а затем, в фигурных скобках, указывается список полей с типами (в нашем случае это id, firstName, lastName и т.д.). Кроме этого, в GraphQL есть понятие интерфейса (как почти во всех популярных языках программирования), и мы можем наследовать от интерфейсов с помощью ключевого слова implements.

Итак, мы сказали пользователям API, что у нас есть персоны. Но как их получить?

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

Определение типа Query

Таким образом мы определили два запроса: person, чтобы получить конкретную персону по её id, и persons, чтобы получить список персон (точнее, специальный Connection type, который нужен для реализации пагинации — но об этом как-нибудь в другой раз).

Резолверы

После того, как мы определили схему нашего API, нам нужно написать резолверы. Резолвер — это функция, которая вызывается, когда пользователь запрашивает тот или иной тип. Она достаёт данные (например, из БД) и возвращает их пользователю. Ниже приведён резолвер для поля person (наше API мы реализуем на TypeScript).

Резолвер, который возращает персону по её ID

А что дальше?

А дальше, по той же схеме, мы определяем остальные типы, которые нужны для нашего API (локации, связи, типы локаций и другие), пишем для них резолверы, сшиваем всё это вместе и запускаем сервер 🚀

Дайте написать запрос!

Теперь перейдём к тому, ради чего здесь все и собрались: написание запросов и получение данных. Запросы к GraphQL API тоже пишутся на SDL. Для того, чтобы было проще отправлять запросы и играться с API, есть GraphQL Playground. Такой есть и у нас, вы можете попасть в него по этой ссылке. Вот что вы увидете, когда откроете Playground:

GraphQL Playground

Тут всё просто: слева пишете запрос, нажимаете на кнопку со стрелкой, а справа получаете ответ.

Давайте же напишем наш первый запрос. Например, получим ФИО всех персон.

Вставляем в Playground следующий запрос:

{
 persons {
  edges {
   node {
    firstName
    lastName
    patronymic
   }
  }
 }
}

И запускаем!

Список персон, полученный от API

Получаем список персон в формате JSON (GraphQL всегда отвечает в JSON).

Кстати, у кого по дефолту стоит английский язык в браузере, тот получит ответ от API на английском языке. Если вы хотите получить ответ на русском, то зайдите во вкладку HTTP HEADERS снизу и добавьте туда следующее:

{
 "Accept-Language": "ru"
}

Попробуем получить ещё что-нибудь интересное. Например, дату рождения. Допустим, вы не знаете как получить дату рождения персоны. Не беда, ведь в Playground есть встроенная документация к API, которая расположена во вкладке DOCS справа. Открываем её и вводим Person в поле поиска.

Поиск по документации

Получили список результатов по нашему запросу. Первая строка — это то, что нам нужно. Кликаем на неё и смотрим, что есть у наших персон.

Документация к типу Person

Видим, что у персоны есть поле birthDate, которое содержит информацию о дате рождения персоны. Добавляем это поле в наш запрос наряду с ФИО (в этом вам поможет autocomplete запросов, встроенный в Playground).

Получили дату рождения


Готово! Как мы видим, к полученным ранее данным добавилась ещё и дата рождения.

А что насчёт запросов посложнее? 😏

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

Давайте запустим следующий запрос:

{
 persons {
  edges {
   node {
    firstName
    lastName
    patronymic
    birthDate
    relations {
     relationType {
      name
     }
     locationInstance {
      name
     }
    }
   }
  }
 }
}

Ответ выглядит вот так:

Из ответа сервера мы видим, что, например, Пётр Ильич Чайковский жил в Доходом доме купцов Елисеевых.

Как вы можете это использовать?

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

Итог

В этой статье мы дали поверхностный обзор на технологию GraphQL. Так же мы показали вам её использование в контексте нашего API. У нас есть ещё много интересного, что мы хотели бы вам рассказать (например, как писать мутации, как работать с пагинацией, что такое фрагменты и т.д.), и мы с радостью это сделаем, если данная статья вызвала у вас интерес. Очень ждём ваших отзывов в комментариях и нашем чате!

Полезное по теме

  1. https://github.com/dh-center/st-retrospect-api — код нашего API
  2. https://api.st-retrospect.dh-center.ru/voyager — визуализация схемы нашего API
  3. https://nodkz.github.io/conf-talks/talks/2018.11.24-holyjs-moscow/ — классная презентация о GraphQL
  4. https://graphql.org — официальный сайт GraphQL

Report Page