Я провел выходные за изучением GraphQL, следуя замечательному руководству на howtographq l. GraphQL - это спецификация, созданная Facebook, которая позволяет интерфейсным и серверным системам говорить на общем языке в отношении схемы данных. По сути, GraphQL позволяет клиентам запрашивать требуемые данные, вместо того, чтобы иметь строгую структуру ответа, которую налагает REST.
GraphQL против REST
В RESTful API у нас есть конечная точка, соответствующая каждому ресурсу. Это приводит к тому, что клиенту приходится делать несколько запросов для сбора всех данных, необходимых для рендеринга пользовательского интерфейса. Например, для форума, подобного Hackernews, для отображения профиля пользователя нам потребуются данные пользователя (/ ‹user_id›), сообщения пользователя (/ ‹user_id› / links) и, возможно, ссылки на пользователь проголосовал за (/ ‹user_id› / голосов). Затем интерфейсная программа объединит эти данные.
Очевидно, что это может привести к избыточной или неполной выборке данных. Ответы на вышеупомянутые запросы API обязательно должны содержать данные, которые не нужны для определенного представления. С другой стороны, это также заставляет клиента делать несколько запросов для сбора всех необходимых данных.
GraphQL спешит на помощь!
GraphQL решает эту проблему, позволяя клиенту запрашивать требуемые данные. В отличие от REST, у которого есть конечная точка для каждого ресурса, GraphQL обычно имеет одну конечную точку API, которая используется для запроса данных. Например, приведенное выше представление, подобное Hackernews, может быть выполнено в GraphQL как:
query { user(id: 123) { name links { url description } votes { url } } }
Приведенный выше запрос при отправке на сервер GraphQL (обычно в виде полезной нагрузки запроса POST) получит имя пользователя с id 123 вместе с url и описание размещенных ими ссылок, а также URL, за которые они проголосовали. Таким образом, он полностью решает проблему избыточной и недостаточной выборки.
Кто-то может возразить, что мы также можем структурировать конечные точки REST вокруг представлений пользовательского интерфейса. Но это неизбежно помешает быстрой разработке, поскольку незначительное изменение пользовательского интерфейса может потребовать огромных изменений в API серверной части для получения дополнительных данных.
Погружение
Чтобы дать краткий обзор, GraphQL использует схему, которая является общей для внутреннего сервера и внешних клиентов.
Схема
Продолжая пример с Hackernews, схема может выглядеть примерно так:
type User { id: ID! username: String! email: String! } type Vote { username: String! url: String! } type Link { id: ID! url: String! description: String! votes: [Vote!]! postedBy: User! }
Восклицательный знак (!) Обозначает обязательное поле. GraphQL поддерживает множество примитивных полей (String, Int, ID и т. Д.), И мы также можем использовать настраиваемые типы в качестве полей. Например, поле postedBy в Link имеет тип User. Также обратите внимание, что vote - это список значений типа Vote. Конечно, мы также могли использовать типы User и Link вместо username и url в Тип голосования, но я старался не усложнять.
Запросы
Запрос GraphQL отправляется от клиента к серверу для получения данных. Он имеет вид:
query { users { username } }
Это позволит получить все имена пользователей с сервера. запрос - это ключевое слово (называемое корневым полем), которое сообщает серверу GraphQL, что запрос предназначен для выборки данных.
У нас также могут быть аргументы в запросах. Более того, GraphQL также поддерживает выборку вложенных объектов. Более сложный запрос будет выглядеть так:
query { links (search: "reddit", first: 2) { description votes { username } postedBy { email } } }
Это приведет к получению первых двух ссылок, содержащих слово «reddit» вместе с их описаниями, именами пользователей, проголосовавших за них, и электронными письмами их авторов.
Мутации
А как насчет записи, обновления и удаления данных? GraphQL поддерживает это с помощью мутаций. Образец мутации будет:
mutation { createUser (username: "adesor", email: "[email protected]") { id username } }
Будет создан пользователь с именем пользователя adesor и адресом электронной почты [email protected], а в ответ будут возвращены id и имя пользователя. Аккуратный! mutation, как и query, - это еще одно корневое поле, которое используется для информирования сервера о том, что он должен выполнить мутацию (а не запрос).
Определение схемы
Чтобы вышеуказанные запросы и мутации работали, нам нужно определить их на нашем сервере. Сервер GraphQL определяет все разрешенные запросы и изменения. В GraphQL есть три корневых типа: Запрос, Мутация и Подписка. Я не буду рассказывать о подписках в этом посте.
Для схемы Hackernews корневым типом запроса будет:
type Query { user(id: ID!): User! users: [User!]! links(search: String, first: Int): [Links!]! }
Это позволяет клиентам запрашивать конкретного пользователя, нескольких пользователей и ссылки. Он также сообщает клиенту, что запросы users и links вернут списки User и Link соответственно, в то время как запрос user вернет одного User. Кроме того, запрос links поддерживает необязательные аргументы search и first, а запрос user имеет обязательный аргумент id.
Точно так же корневой тип мутации будет определяться как:
type Mutation { createUser(username: String!, email: String!): User! }
Следовательно, клиент может создавать новых пользователей, используя мутацию createUser и передавая username и email в качестве аргументов, оба из которых являются обязательными.
Все эти запросы и изменения реализуются с помощью функций resolver, которые по сути являются функциями с тем же контрактом, что и соответствующий запрос или мутация. Например, преобразователем для мутации createUser будет функция, которая принимает строковое имя пользователя и строковое электронное письмо и возвращает объект пользователя.
Резюме
GraphQL меняет способ работы веб-приложений. Такие компании, как Facebook, Github и Pinterest, и многие другие, используют GraphQL. Он реализован почти для всех известных веб-языков и фреймворков.
GraphQL широко используется в качестве агрегатора данных, где он действует как промежуточное программное обеспечение между несколькими источниками данных (базой данных, сторонними API-интерфейсами и устаревшими системами), чтобы предоставить клиентам единую точку входа. Это также облегчает жизнь всем, имея общую и запрашиваемую схему.
Однако есть несколько подводных камней (аутентификация, регулирование и т. Д.), Которые необходимо учитывать при реализации сервера GraphQL. Вы найдете учебник howtographql (ссылка на него выше), который станет отличной отправной точкой для изучения GraphQL, а также позаботится о таких предостережениях.