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

ЭкоСистема

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

Некоторые из предложений Apollo с открытым исходным кодом включают:

  • apollo-server - Apollo Server - это сервер GraphQL, который работает с любой схемой GraphQL, соответствующей спецификации GraphQL.
  • apollo-client - клиент Apollo - это полнофункциональный клиент GraphQL с поддержкой кеширования и интеграцией с React, Angular и другими интерфейсными фреймворками. Он позволяет легко создавать компоненты пользовательского интерфейса, которые извлекают данные с помощью GraphQL.
  • apollo-tooling - Apollo CLI объединяет ваши клиенты и серверы GraphQL с инструментами для проверки вашей схемы, проверки ваших операций на совместимость с вашим сервером и генерации статических типов для повышения безопасности типов на стороне клиента.

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

В оставшейся части истории мы разделим темы на два основных раздела, а именно на стороне сервера и на стороне клиента.

Сторона сервера - Сервер Apollo

Apollo Server - это сервер GraphQL, который помогает клиенту GraphQL подключаться и извлекать данные. Apollo Server работает на Node.js. Используя определенные преобразователи, определения типов и схему, Apollo Server выполняет запрос GraphQL. Установить и запустить Apollo Server сравнительно проще.

Опубликовано несколько пакетов, которые позволяют Apollo Server легко интегрироваться с популярными библиотеками промежуточного программного обеспечения Node.js, такими как express, Koa, hapi и т. Д. Ознакомьтесь с этой ссылкой, чтобы узнать о доступных интеграциях.

Более интересные вещи, происходящие на стороне сервера, обсуждаются ниже.

Федерация

Федерация - это интересная концепция, которая позволяет вам составить несколько серверов GraphQL и представить их в виде единого унифицированного графа. Согласно Principled GraphQ L, наличие единого графа для всей вашей организации и объединение более мелких частей вместе является ключом к обеспечению четко определенного, стабильного и непротиворечивого графа.

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

Хотя существует только один граф, реализация этого графа должна быть объединена между несколькими командами.

- Принципиальный GraphQL

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

В качестве примера на приведенном выше рисунке представлено несколько серверов GraphQL, разработанных группами продуктов, обзоров и инвентаризации, составленных вместе и представленных через «шлюз». Потребители из Интернета / iOS отправляют свой запрос GraphQL на шлюз, а шлюз абстрагирует выборку данных с различных базовых серверов GraphQL.

Для этого использовались два пакета Apollo:

  • @ Apollo / federation - предоставляет утилиты для создания микросервисов GraphQL, содержащих федеративную схему.
  • @ Apollo / gateway - предоставляет утилиты для объединения микросервисов GraphQL и представления их в виде единого графа.

Модуляризация

В зависимости от размера кодовой базы могут возникнуть ситуации, когда код на сервере GraphQL необходимо организовать по-другому. Например, на изображении ниже представлена ​​ситуация, когда код внутри службы инвентаризации необходимо организовать в модуль 1 и модуль 2.

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

Суть выше представляет собой создание объекта схемы GraphQL из собственных модулей es (Модуль 1 и Модуль 2) с использованием функции buildFederatedSchema. Затем созданный объект схемы передается ApolloServer для его запуска и запуска с использованием модульного кода.

Кеширование

Кеширование в GraphQL вызывает много споров. Это связано с тем, что большинство клиентов GraphQL используют HTTP POST для получения данных с сервера GraphQL. Поскольку кэшировать POST запросов не идеально, часто говорят, что «GraphQL нарушает кеширование». Обычный обходной путь - преобразовать сетевые вызовы GraphQL для использования GET вместо POST и добавить CDN перед вашим сервером GraphQL. Затем сервер GraphQL настраивается для добавления Cache-Control: max-age=xxxx header в ответ, на основе которого результаты кэшируются в CDN.

Используя cacheControl directive, можно объявить параметры управления кешем для отдельных типов и полей GraphQL. Затем Apollo Server объединяет эти подсказки кеша в общую политику кеширования для ответа. maxAge запроса - это минимум maxAge во всех полях вашего ответа.

Apollo Server также дает возможность настраивать и кэшировать полные ответы в популярных серверных приложениях, таких как Redis, Memcached и т. Д. Кэшированные ответы соответствуют подсказке maxAge кеширования.

Плагин API

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

Написать плагин Apollo очень просто. Простой объект JavaScript, который реализует одну или несколько функций, реагирующих на вышеупомянутые события, становится плагином. Мы полагаемся на плагины для ведения журнала и обработки файлов cookie.

Другие

  • Источники данных - RESTDataSource - это тонкая абстракция над выборкой, которая по умолчанию поставляется с Apollo Server. Он используется для разрешения данных из REST API. RESTDataSource имеет встроенную поддержку кэширования, предотвращения дедупликации запросов и обработки ошибок. В этой статье вы найдете подробное описание того, как работает RESTDataSource. Другие поддерживаемые сообществом пакеты источников данных, такие как SQLDataSource и MongoDataSource, также заслуживают внимания.
  • Обработка ошибок - Apollo Server поставляется с набором предопределенных ошибок, таких как AuthenticationError, ForbiddenError, UserInputError и общий ApolloError. Это значительно упрощает обработку ошибок и представление их во внешнем интерфейсе.

Клиентская сторона - Клиент Apollo

Apollo Client - это современный клиент GraphQL, управляемый сообществом, гибкий и разработанный для работы с любым сервером GraphQL, совместимым со спецификацией GraphQL. Apollo Client содержит много хороших вещей, о которых мы поговорим позже.

Государственное управление

Управление состоянием пользовательского интерфейса, возможно, является одной из важнейших частей интерфейсного приложения. Настроить управление состоянием и объединить его с вызовами GraphQL может быть немного сложно. Apollo хорошо справляется с этим с помощью пакета @ apollo / client. Apollo Client - это универсальное решение как для управления локальным состоянием, так и для удаленного извлечения данных. Это избавляет от множества сложностей. Apollo Client поставляется с встроенной поддержкой React и поддерживается сообществом пакеты для Angular, Vue и т. Д. Публикуются отдельно.

Использование Apollo Client устраняет необходимость в дополнительных библиотеках управления состоянием (Redux, MobX и т. Д.) И написании обработчиков асинхронных действий (redux-thunk , redux-saga и т. Д.).

Аполлон Ссылка

Apollo предоставляет способ настройки сетевого уровня с помощью библиотеки под названием Apollo Link. Функциональные возможности, определенные в составных единицах, называемых Ссылки, применяются одна за другой, когда клиент выдает запрос. Это мощно, потому что позволяет вам контролировать, как можно отправлять запросы. Например, вы можете использовать apollo-link-ws и подключить его для отправки запросов GraphQL через WebSockets.

На приведенном выше рисунке представлен клиент, отправляющий запрос GraphQL, операция распространяется по ссылкам, а данные возвращаются с сервера.

Ссылки в основном бывают двух типов:

  • Прерывание ссылки
  • Неограничивающая ссылка

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

Ссылки действуют как промежуточное программное обеспечение, которое находится между уровнем, на котором Клиент выдает запрос GraphQL, и получением ответа. Это открывает возможности для выполнения интересных побочных эффектов, таких как повторная выборка нового веб-токена JSON (JWT) по истечении срока действия. Apollo предоставляет интерфейс для написания ваших собственных ссылок и их компоновки. Это довольно мощно, а возможности безграничны.

Семантика

Синтаксис и семантика играют решающую роль в написании кода. Важно работать в среде, где синтаксис и семантика дают положительный опыт разработчикам. Мы считаем, что комбинация «TypeScript + React + Apollo Hooks» менее многословна и более управляема, что способствует лучшему взаимодействию с разработчиками. Когда размер кодовой базы увеличивается, типы и аннотации типов очень помогают. Кроме того, во время компиляции обнаруживается множество ошибок, что сокращает количество человеческих часов, затрачиваемых на исправление ошибок.

  • Typescript - определения типов Typescript сразу поддерживаются клиентом Apollo, который не требует дополнительной установки.
  • React Hooks поддержка - Apollo Client предоставляет useQuery, useMutation, useSubscription, useLazyQuery хуки, которые можно использовать с вашими компонентами React.

Суть выше показывает пример использования ловушки useQuery для получения деталей для страницы со списком фильмов. Мы также можем указать информацию о типе результата, в этом случае <GetMovies> обозначает тип данных результата, а GET_MOVIES содержит строку запроса GraphQL. Вы можете видеть, что использование хуков сокращает количество шаблонов, а поток управления в этом компоненте довольно прост.

Кеширование

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

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

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

Используя пакет apollo-link-persisted-queries, очень легко настроить Apollo Client для использования APQ.

SDK

Помимо библиотек Javascript, Apollo также издает SDK для мобильной разработки. Это хорошая новость, если вы планируете использовать один и тот же бэкэнд GraphQL как для мобильных, так и для веб-клиентов. Более подробную информацию о SDK для iOS и Android можно найти по ссылкам ниже.

Другие

  • Реактивные переменные - Apollo Client v3 представил новый механизм для хранения состояния вне кеша Apollo Client с использованием реактивных переменных. Как следует из названия, когда реактивная переменная обновляется, активные запросы к ней запускают автоматический повторный рендеринг компонентов, которые от нее зависят. Это полезно для хранения краткосрочных данных, таких как отображение предупреждения.
  • Тестирование. Используя MockedProvider, можно высмеивать ApolloProvider с точными ответами, не совершая сетевых вызовов. Это помогает изолировать и протестировать поведение компонента.

Сообщество

  1. Команда Apollo постоянно продвигает контент через посты в блогах и видео на YouTube.
  2. Они неплохо справляются с документацией, предоставляя хорошие примеры и варианты использования.
  3. Недавно Apollo провел Graphql Summit, на котором были представлены интересные доклады самых разных спикеров.

В целом компания, стоящая за Apollo, проделала похвальную работу по развитию сообщества GraphQL.

Недостаток

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

В настоящее время все основные компоненты, такие как apollo-server, apollo-client и т. Д., В экосистеме Apollo имеют открытый исходный код, который, я считаю, останется прежним. Поскольку в мире программного обеспечения хорошие вещи не длится долго бесплатно, вполне возможно, что вы можете заблокировать поставщика с помощью Apollo, и они могут начать взимать $ $ $ $. Если цены разумные и пока они приносят пользу вашему бизнесу, это не должно быть проблемой. Но ваш пробег может отличаться, и об этом следует помнить.