GraphQL - относительно новый способ создания пользовательских интерфейсов и API для потребителей. По сути, это язык запросов, поддерживаемый строго типизированной схемой, что позволяет легко писать удобочитаемые запросы для получения именно тех данных, которые вам нужны. По сравнению с REST, ответы на которые диктует сервер, запросы GraphQL полностью передают власть в руки клиента.
Однако на самом деле GraphQL - это просто спецификация, описывающая API. Многие функции, которые можно ожидать от API, такие как логика авторизации / аутентификации, двунаправленная связь или ограничение скорости, еще предстоит реализовать. Недавно запущенный Slash GraphQL - это полностью управляемый бэкэнд GraphQL, который берет на себя всю тяжелую работу по настройке GraphQL API, позволяя вам сосредоточиться на создании своего приложения.
В этой статье мы будем создавать книжный магазин электронной коммерции, основанный на Slash GraphQL. Чтобы продемонстрировать гибкость сервиса, мы также будем извлекать данные из другого источника - Goodreads API - и интегрировать их в наши ответы.
Мы будем создавать наше приложение с использованием Node.js, поэтому на вашем компьютере должна быть установлена как минимум версия 12. Создайте каталог с именем slashql_bookstore и перейдите в него из командной строки.
Создание бэкэнда GraphQL
Настройка Slash GraphQL
Настроить учетную запись на Slash GraphQL просто - вы можете мгновенно войти в свою учетную запись GitHub. Платформа предлагает бесплатную пробную версию, которая будет работать для этой статьи (затем будет установлена фиксированная плата в размере 9,99 долларов США в месяц за данные объемом до 5 ГБ).
После того, как вы создали учетную запись, вам нужно будет создать новую серверную часть:
1. Щелкните «Запустить новый сервер».
2. Назовите бэкэнд «Книжный магазин».
3. Щелкните «Запустить».
Вот и все! Теперь у вас есть сервер, созданный для вас в регионе AWS.
Определение схемы GraphQL
Каждый сервер GraphQL имеет строго типизированную схему, которая определяет объекты и поля, доступные потребителям.
Щелкните «Схема» и вставьте следующие строки:
type Book { id: Int! isbn: Int! title: String! @search(by: [fulltext]) author: Author! } type Author { id: Int! firstname: String! lastname: String! }
Здесь мы определили два типа - Книга и Автор, которые будут представлять данные в нашем API. Из множества тонкостей, которые предоставляет Slash GraphQL, его поддержка пользовательских директив - одна из самых удобных. Здесь, например, аннотируя поле title с помощью @search, мы можем предоставить нечеткий текст без каких-либо дополнительных действий.
Нажмите «Развернуть», чтобы отправить эту схему в производство.
Настройка данных
Переходим к вставке данных. Мы можем использовать API Explorer не только для добавления данных, но и для их запроса. Чтобы заполнить наш бэкэнд GraphQL, мы определим список книг и их авторов с помощью мутации, которую Slash GraphQL удобно предоставляет нам, на основе нашей схемы:
mutation AddData { addBook(input: [ {id: 1, title: “The Sound and The Fury”, isbn: 9780394747743, author: {id:1, firstname: “William”, lastname: “Faulkner”}}, {id: 2, title: “Light in August”, isbn: 9780394711898, author:{id:1, firstname: “William”, lastname: “Faulkner”}}, {id: 3, title: “Giovanni’s Room”, isbn: 9780141032948, author:{id:2, firstname: “James”, lastname: “Baldwin”}}, {id: 4, title: “The Fire Next Time”, isbn: 9780140182750, author: {id:2, firstname: “James”, lastname: “Baldwin”}}, {id: 5, title: “To The Lighthouse”, isbn: 9780140274165, author: {id:3, firstname: “Virginia”, lastname: “Woolf”}}, {id: 6, title: “Orlando”, isbn: 9780241284643, author: {id:3, firstname: “Virginia”, lastname: “Woolf”}} ]) { numUids } }
Нажмите гигантскую кнопку «Воспроизвести», чтобы добавить эти данные в серверную часть.
Теперь давайте запустим запрос, чтобы убедиться, что эти данные присутствуют:
query GetBooks { queryBook { title isbn author { firstname lastname } } }
Вы должны увидеть ответ, в котором будут показаны все ранее введенные данные.
Сборка сервера
Теперь мы воспользуемся Express, чтобы настроить базовый сервер API, который предоставит пользователям доступ к этому источнику Slash GraphQL. Наш Express-сервер действует как не более чем интерфейс для передачи запросов в Slash GraphQL. Его самые важные строки таковы:
const BACKEND_URL = “https://rampant-arm.us-west-2.aws.cloud.dgraph.io/graphql" async function fetchGraphQL(operationsDoc, variables) { const result = await axios({ method: ‘POST’, url: BACKEND_URL, headers: { ‘Content-Type’: ‘application/json’, }, data: JSON.stringify({ query: operationsDoc, variables, }), }) return result.data } const query = ` query { queryBook { title isbn author { firstname lastname } } } ` app.get(‘/’, jsonParser, async (req, res) => { let gqlResponseData = await fetchGraphQL(query, {}) res.render(‘index’, { books: gqlResponseData.data.queryBook }) })
Здесь мы определили вспомогательную функцию fetchGraphQL, которая устанавливает необходимые заголовки и данные для отправки в Slash GraphQL. Имейте в виду, что вам нужно будет изменить BACKEND_URL, чтобы он соответствовал URL-адресу, который вам дает Slash GraphQL. Затем мы пишем запрос GraphQL, который определяет данные, которые нам нужны. Наконец, мы настраиваем маршрут для получения этих данных, а затем отображаем их в нашем представлении:
<div class=”container”> {{#each books}} <div class=”row”> <div class=”col-md-4"> <h2>{{title}}</h2> <h4>{{author.firstname}} {{author.lastname}}</h4> <p><strong>ISBN:</strong> {{isbn}}</p> </div> </div> <hr> {{/each}} </div>
Наше мнение поддерживается популярной библиотекой шаблонов handlebars. Мы можем передать наши данные JSON во фрагмент HTML и перебирать ключи и значения, что значительно упрощает отображение информации. Здесь мы используем цикл #each для просмотра каждой книги, возвращаемой GraphQL API, а затем вставляем данные в теги HTML. Вы заметите, что у нас есть заполнители, которые соответствуют именам ключей JSON; они заменяются реальными данными при просмотре страницы.
После того, как вы установили все зависимости с помощью npm, запустите сервер с node server.js. Затем перейдите на localhost: 3000 в своем браузере:
Вы должны получить тот же ответ, что и API Explorer Slash GraphQL.
Расширить сервер
В качестве последнего шага мы хотим предоставить некоторые данные рецензентов об этих книгах. Но мы не хотим создавать здесь фиктивные данные; вместо этого мы будем использовать Goodreads API. Прежде чем продолжить, убедитесь, что вы создали там учетную запись и получили ключ API.
Одна из многих вещей, которыми выделяется Slash GraphQL, - это способность объединять разрозненные источники данных в один интерфейс GraphQL. Возможно, вы захотите выполнять вызовы к другим конечным точкам API, находящимся под вашим контролем. Для поддержки этого Slash GraphQL предоставляет директиву @custom, которая позволяет вам реализовать собственное поведение для полей и преобразователей GraphQL.
Во-первых, давайте добавим нашу рейтинговую информацию к существующей схеме:
type Rating @remote { ratings_count: Int! average_rating: Float! }
Наш тип рейтинга определяет имена полей, которые мы ожидаем от API book.show_by_isbn. Нам не нужно определять все поля, предоставляемые их REST API, только те, которые нам интересны. Slash GraphQL знает, как преобразовать этот ответ в GraphQL.
Что касается полей, нам нужно будет указать URL-адрес, по которому мы хотим вызвать, вместе с методом HTTP:
type Book { # … rating: Rating @custom(http: { url: “https://goodreads-api-munger.glitch.me?isbn=$isbn", method: GET }) # … }
Вы можете заметить здесь, что мы на самом деле призываем к проекту с ошибками. API Goodreads не возвращает данные JSON в удобном и удобном формате. Мы будем обращаться к промежуточному серверу, который переведет данные в более читаемый формат. Детали этого сервера не так уж и важны (но вы можете проверить это, если хотите). важно отметить, что этот URL может заменять что угодно, что может быть очень полезно, если вы взаимодействуете с данными, которые принадлежат вам.
Еще одна удивительная вещь - Slash GraphQL заменит вам данные. Видите ту часть URL-адреса, в которой написано: $ isbn? В зависимости от объекта, возвращаемого нашим запросом, Slash GraphQL подставит реальное значение поля для этой переменной. Это делает ваши URL-запросы гибкими и простыми в управлении.
Это все, что нам нужно сделать, чтобы ввести некоторые пользовательские данные. Теперь наш запрос GraphQL может просто добавить это поле рейтинга, чтобы ввести эти внешние данные. Давайте заменим запрос в нашем server.js на этот:
const query = ` query { queryBook { title isbn rating { ratings_count average_rating } author { firstname lastname } } } `
И давайте обновим представление, чтобы отобразить эту информацию:
<div class=”container”> {{#each books}} <div class=”row”> <div class=”col-md-4"> <h2>{{title}}</h2> <h4>{{author.firstname}} {{author.lastname}}</h4> <p><strong>ISBN:</strong> {{isbn}}</p> <p>Rating: {{rating.average_rating}} (out of {{rating.ratings_count}} votes)</p> </div> </div> <hr> {{/each}} </div>
Если вы перезапустите сервер и вернетесь к localhost: 3000, вы также должны увидеть заполненные рейтинги:
Заключение
Slash GraphQL позволяет невероятно легко настроить GraphQL API производственного уровня, но мы коснулись лишь поверхности. Помимо возможности комбинировать разрозненные местоположения данных, он также поддерживает авторизацию, подписку и даже шифрование.
Вы можете получить полный исходный код этого руководства на GitHub. Если вы еще этого не сделали, не забудьте зарегистрироваться в Slash GraphQL - не стесняйтесь делиться своими творениями с остальной частью сообщества Dgraph.