conf-talks

GraphQL на фронтенде

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

GraphQL-клиенты и фетчеры

Relay

Relay – GraphQL-клиент разработанный в Facebook (теми кто и разработал сам GraphQL, и есть опыт разработки Flux). Самый старый представитель, самый богатый по функционалу и, соответственно, самый сложный в изучении. Сильный упор на производительность, с чем связана сложность кодовой базы и архитектуры. В мае 2019 Facebook.com запускается на нем в продакшене. В последнее время документация стала получше по сравнению со временем, когда зарождался Apollo. И вроде код стал почище. Но все еще слабое комьюнити, т.к. в основном разработчики целятся на свои фейсбуковские нужды и проблемы. Баги с удовольствием правят, а вот чтобы им занести новую фичу – надо сильно постараться и долго их ждать. Разработка ведется в фейсбуковском Fabricator’е, а то что мы видим в гитхабе - это просто публичная копия. Поэтому до разрабов тяжело достучаться.

ApolloClient

ApolloClient – переписан с оглядкой на Relay, обрезкой “непонятного” функционала, более простым кодом и с понятной документацией. Сильно стараются соблюсти баланс между фишками и сложностью. Но с каждым годом все больше и больше приходит понимание “непонятных” вещей релея, которые они так или иначе реализовывают. Ко всему прочему запилили много дополнительных инструментов, пакетов и интеграций. Очень хорошее комьюнити. Разработка полностью ведется в гитхабе.

Lokka

Lokka – очень простой vanilla JS клиент для отправки GraphQL-запросов. Есть свой кислый кеш/стор, на изменения которого можно подписаться, но вот если соседние запросы поменяют данные, то обновления не прилетают. Нет фрагментов.

graphql-hooks

graphql-hooks – простой JS клиент для React (c 16.8.0), построенный на React хуках. У ребят большие амбиции заменить собой ApolloClient. В преимуществах заявляют, что на 93% их бандл меньше чем аполловский. На начало мая 2019, нет фрагментов, нет полноценного нормализованного кеша/стора (есть псевдо кеш целых запросов), нет подписок на изменения в кеше данных (если они вызваны другими запросами) и много еще чего. По мне, так и функционала у них на 93% меньше, чем у Аполло. Таким образом если вам не нужно ничего кешировать и не важно поменялись ли данные в соседнем запросе – то однозначно надо брать. В общем, сильно напоминают времена, когда Apollo таким же образом начинала бороться с Relay и искать места под солнцем (комьюнити).

urql

urql – простой клиент для React, предоставляет как и обычные компоненты Query и пр., так и hooks. Нет фрагментов, нет полноценного нормализованного стора.

graphql.js

Не путать с graphql-js репкой, которая является имплементацией GraphQL спецификации на NodeJS для сервера.

graphql.js – vanilla JS клиент, умеет работать с фрагментами, но нет своего локального стора и соответственно нет подписок на изменения данных в сторе. Но то что работает с фрагментами, это похвально.

graphql-request

graphql-request – 150 строчек кода от Prisma. Максимально простой. Просто берет оборачивает fetch с настройками, и такого клиента предоставляет для многоразового использования, куда необходимо передать только запрос и переменные. Просто и удобно. Хотите устанавливайте в виде пакета, хотите копипастой к себе утащите в проект. Нет стора, нет фрагментов.

fetch

fetch – самый легковесный способ сделать запрос:

fetch('https://example.com/graphql', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ query: '{ posts { title } }', variables: {} }),
})
  .then(res => res.json())
  .then(res => console.log(res.data));

Что такое нормализованный кэш/стор?

Вообще, отличить полноценный GraphQL-клиент, от фетчера (простой тулзы вызова GraphQL-запросов) можно по наличию нормализованного кеша/стора. Это когда ваш сильно вложенный ответ от графкуэля, автоматически пересобирается в плоский вид: ключ (уникальный id, обычно base64(__typename + ':' + id)) и значение (набор скалярных параметров и ссылок на другие записи по ключу). И в таком плоском виде ключ-значение записывается в стор/кэш. Т.е. в таком случае вам не важно сколько раз вам вернулись данные и насколько глубоко они были вложены в графкуэль запросе, они на клиенте будут храниться максимально компактно и удобно.

На данный момент нормализованный кеш/стор есть только у Relay и ApolloClient, а все остальные просто навернутые фетчеры данных.

Собственно реализация этого нормализованного кеша/стора и является самой важной фичей, которая привносит уйму кода в библиотеку, чтоб из коробки дать вам следующие фишки:

Эти фишки нормализованного стора, которые доступны из коробки, сильно упрощают жизнь. Особенно это понимают ребята, которые руками собирают свои “хитрые” сторы в Redux или Flux, пилят экшены, редьюсеры и уже потом все это дело подписывают на свои компоненты. В последнее время это стало модно называть бойлерплейт кодом. Код который по чьим-то сферическим оценкам в интернетах может достигать 80% от общей массы.

Собственно автоматически кеш/стор из коробки (который не надо писать) и дает связка GraphQL + Relay/ApolloClient (и в этой связке вам не нужен Redux). А вот если вам просто жизнь не мила без Redux, то можно обратить внимание на оставшиеся фетчеры GraphQL-запросов из рассмотренного списка, возможно они будут вам чем-то полезны.

Кстати, по теме у меня еще есть одна статья: Redux - бойлерплейт