Итак, GraphQL — это язык запросов, применяемый Facebook для извлечения данных из графовых СУБД. Язык оказался настолько удачным, что потенциальная сфера его применения значительно шире — его называют «убийцей REST» и даже прикрутили его к реакту в качестве очередного движка управлениями моделями данных. Совсем вкратце о том, что такое GraphQL:
— запрос — это список полей, которые нужно вернуть в ответе. Возвращаются только те поля, которые были запрошены
— поле может оказаться методом с одноименным названием — тогда прямо в запросе указываются параметры этого метода: {name, surname, age, getLikesCount(since: «01.01.2016»)}
— если значение поля или метода — объект, то для него так же надо явно указать список полей: {name, surname, age, bestFriend: {name}}
Есть много разных мнений о том, что именно в нем такое инновационное, но, я думаю, что самая интересная идея вот в чем:
Модель данных — это частный случай модели API
И в самом деле, если в произвольном json заменить поля на методы с пустым списком параметров, то получится какое-то урезанное API:
{
name: "John",
age: 25
friends: [{
name: "Jenny",
age: 24
}]
}
превращается в
interface Human {
name(): string
age(): int
friends: Human[]
}
Этот пример демонструет важное следствие — если API и данные — это одно и то же, то API может возвращать ссылки на другие API, т.е. на объекты, предоставляющие методы, возвращающие данные (или другие API). Важный момент — методы вовсе не обязаны быть идемпотентными, это вполне может быть update/delete или просто вызов некой бизнес-логики.
Ничего не напоминает? Например, граф объектов в работающей программе? С учетом того, что запрос GraphQL, по сути, представляет из себя список методов на корневом объекте, которые нужно вызвать, а также прочих фич:
— строгая типизация
— поддержка интерфейсов
— документированное представление схемы в виде структуры данных
мы получаем, что GraphQL позволяет выставить в сеть произвольный объект! И, в частности, активную доменную модель, самописную или собранную при помощи ORM типа Hibernate
Многим не нравится избыточность GraphQL, его набор фишек и примочек, которыми он оброс за время использования его в фейсбуке. Многие из них имеют смысл только в контексте node.js и конкретного стиля разработки. Но — если у нас есть схема и мы сказали RPC, то очевидное решение — кодогенерация. Если многословные запросы со всем этим `query`, `mutation` и объявлением переменных будут скрыты за API, то этот недостаток нивелируется.
Итого, на выходе получается RPC фреймворк, позволяющий выставить в сеть типизированный, документированный, объектный API, использующий в качестве транспорта json и примитивное (парсер пишется с полплевка) подмножество GraphQL. А также клиентский кодогенератор, предоставляющий удобный интерфейс для вызова.
Осталось его написать :)
Спасибо.
Комментарии (24)
boolive
28.01.2017 18:52Меня название смущает, почему "Graph"? Я от этого ожидаю выборки по графу, с условиями в глубину, ширину и всякое другое. А потом думаю, что это только язык, под который нужно писать парсер на все сложные выборки. С какого момента, может уровня сложности проекта, GraphQL становится оправдан? Начинать проект проще на REST, делая узко заточенное API вместо универсального. Вообще универсальных решений опасаюсь.
Методы API в возвращаемых объектах — интересная особенность. Какой ценной она реализуется на клиенте и сервере? Легко ли без написанного клиента тестировать такое апи, писать сервер-заглушку?
Scf
28.01.2017 20:42На самом деле все очень просто) На яваскрипте к примеру:
{ human: function (name) { if (name == "Anna") return { name: () => "Anna", lastName: () => "Ivanova", friends: () => dao.getFriends(name) }; return null } }
И вот такой запрос:
human("anna") { name, friends }
вернет
{human: {name: "Anna", friends: [...]}}
Логика выполнения запроса вот такая:
- на корневом объекте вызвать метод humans с параметром Anna
- на получившемся объекте вызвать методы name() и friends()
- результат сложить во вложенную мапу по принципу имя_функции: значение
Итог — мы только что одной короткой строчкой дернули два серверных API.
taujavarob
31.01.2017 16:00Супер. Круто. Понятно и… прогрессивно!
на корневом объекте вызвать метод humans с параметром Anna
тогда, наверное:
humans: function (name) {
Jermes
GraphQL — язык запросов. REST — стиль построения архитектуры распределенного приложения. Как мягкое может убить теплое?
Scf
То, что касается архитектуры, у них более-менее одинаковое. stateless, HTTP, кеширование, унифицированный интерфейс. Отличается представление ресурсов — GraphQL предлагает графовую модель, а REST — иерархическую. Плюс типизация плюс больше гибкости — некоторые вызовы "упаковываются" в модель REST с некоторым трудом. Плюс есть надежда, что GraphQL API получится меньше в размерах, понятнее и проще поддерживаемым. Время покажет.
Jermes
Это несравниваемые вещи. GraphQL находится в одном ряду с JSON/XML-RPC и SOAP, но не с REST. И ждет его такая же участь.
Carburn
REST является альтернативой RPC.
Jermes
Не является. REST — гораздо больше чем RPC.
rraderio
Что можно сделать с REST и невозможно с RPC?
Jermes
REST emphasizes scalability of component interactions, generality of interfaces, independent deployment of components, and intermediary components to reduce interaction latency, enforce security, and encapsulate legacy systems.
rraderio
Т.е. RPC не соответствует ничему из этого списка? Чем REST безопаснее RPC?
Jermes
REST — это подход к построению распределенных приложений или как более точно называют — архитектурный стиль, куда входит набор принципов и ограничений, реализация которых обеспечивает распределенному приложению набор определенных важных свойств таких как: Performance, Scalability, Simplicity, Modifiability, Visibility, Portability, Reliability. RPC — это некое соглашение для вызова удаленного кода и все. RPC можно рассматривать как составную часть REST.
rraderio
Т.е. RPC не обеспечивает ничего из: Performance, Scalability, Simplicity, Modifiability, Visibility, Portability, Reliabilit", так?
Jermes
Так. Само по себе RPC ничего не обеспечивает.
OlegYch_real
сам по себе и REST ничего не обеспечивает
особенно когда рестом обзывают любой json over http интерфейс
Jermes
REST — это набор принципов и ограничений, следование которым обеспечивает вышесказанное.
Какой спрос, когда нечто называют тем, чем оно не является?
OlegYch_real
REST это набор сказок и их пересказов
спроси пять человек что такое REST — получишь десять ответов
Jermes
Что такое REST написано здесь http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm Спрашивать никого не надо.
rraderio
А REST обеспечивает? Чем REST обеспечивает Performance?
oxidmod
Хотябы безпроблемным масштабированием за счет отсутсвия состояния на бекенде (в идеале конечно)
Jermes
http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm