В части первой мы рассказали, как мы сюда попали, а как насчет кода?

Я выбрал Go для кода (на стороне сервера) в этом случае, без особой причины, кроме того, с чем я играл в последнее время (а также чтобы показать, что нам не просто нужно использовать JavaScript). Стиль кодирования библиотек GraphQL в разных языках, как правило, довольно схож, поэтому вы должны иметь возможность следовать за ним.

Итак, начнем с библиотек, которые собираемся использовать. encoding / json, потому что в этом примере мы преобразуем конечные точки REST в GraphQL. github.com/graphql-go/* - это библиотека, которую мы здесь используем. net / http для нашего сервера, а остальное - просто для наших различных фиктивных ответов.

Теперь GraphQL имеет встроенные типы и пользовательские типы (которые в конечном итоге состоят из встроенных типов прямо внизу). Итак, давайте определим некоторые из наших типов, составляющих нашу схему.

Здесь мы определили три типа. Пользователь, содержащий имя и список учетных записей. Тип учетной записи, которую использует пользователь. И тип адреса.

Как видите, в конечном итоге это набор из Strings, Ints и Float.

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

Итак, давайте немного разберемся с этим. Легкие биты - это «последний пост», «случайный» и «двойной» разделы. У каждого из них есть тип (String, Int и Int соответственно), Описание (для нашей автоматической документации ) и функцию Resolve, которая выполняет фактическую работу. Определяя наши возвращаемые типы как «NewNonNull», мы всегда можем гарантировать, что они будут определены. Чтобы сделать их допускающими значение NULL, в будущих версиях схемы будет нарушена, поэтому убедитесь, что они никогда не будут допускать значения NULL. Сделайте здесь осторожность и сделайте их допускающими значение NULL (затем проверьте код на стороне клиента).

Кроме того, наш раздел «double» может принимать аргументы. Еще раз, не допускает значения NULL (т.е. обязательное поле). Прелесть GraphQL в том, что если мы попытаемся вызвать это без аргумента, будет возвращена ошибка. Кроме того, если мы попытаемся вызвать это с помощью String вместо Int, также будет возвращена ошибка. Самодокументирующийся код прекрасен.

Разделы «пользователь» и «адрес» практически одинаковы и представляют собой лишь быстрый и грязный метод получения JSON от конечной точки REST и его передачи. Указание полей в вашем запросе GraphQL делает все волшебство, передавая обратно только необходимые данные. В производственной системе реальность такова, что вы, вероятно, захотите немного больше проверить ответ здесь.

Наконец, мы устанавливаем этот тип запроса схемы (позже здесь мы добавляем тип мутации). Затем запускаем сервер.

Для полного проекта я разместил базовое репо на github. Mocks.sh предназначен для добавления имитаторов к работающему серверу Mountebank.

Итак, теперь у нас есть базовый сервер, и мы можем поиграть с ним, даже не написав клиента. Запустите сервер (обычно go get && go run main.go), затем перейдите к http: // localhost: 8090 / graphql. Вы увидите следующий экран.

Итак, довольно простой интерфейс. Введите запрос слева, нажмите "Воспроизвести", и вы увидите результат справа. Прелесть в том, что у вас есть документация (крайняя правая вкладка) И автозаполнение.

Начнем с простого.

Введите это, нажмите кнопку воспроизведения, и вы должны увидеть следующее (число, вероятно, будет другим).

Простой. Но поскольку этот запрос относится к одному большому типу, мы можем получить сразу несколько вещей, попробуйте следующее

Подождите минутку, где запятые и что это за тест внизу? Что ж, отвечая на первый вопрос, мы всего лишь JSON-подобный, а не настоящий JSON. Не стесняйтесь добавлять запятые, если хотите, но это совершенно необязательно.

Теперь перейдем ко второй части: «test» внизу задает псевдоним поля. Красота этого заключается в том, что вы можете запрашивать одни и те же данные несколько раз, просто задавая им другой псевдоним (подумайте о SQL-запросе, в котором вы присоединяете таблицу к самой себе, вы должны указать псевдоним по крайней мере одной из этих таблиц, чтобы ссылаться на нее. правильно).

Не стесняйтесь немного поиграть с этим. Попробуйте ввести строку в «val» из double. Запросить несуществующее поле и т. Д.

Теперь немного посложнее. Давайте обратимся к одному из этих более сложных типов.

Не намного сложнее? Вам просто нужно указать поля, которые вам нужны, в типах. Здесь тип пользователя также содержит дополнительные данные, но мы их не запрашиваем, поэтому они не возвращаются. Это ОГРОМНО. Здесь вы можете сэкономить довольно много трафика и ненужной обработки. Те из нас, у кого есть ограничения на объем данных, будут любить вас за это.

Одна из последних вещей, которые я покажу вам в этом вступлении, - это присвоение имен запросам.

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

Итак, запросы данных - это хорошо, как же нам изменить данные? Вот здесь и появляются мутации. Как и в случае с REST, нет ничего, что могло бы физически помешать вам делать это в обычных запросах (или GET с REST), но, как и все хорошие программисты, вы хотите, чтобы ваш код был правильным, не так ли?

Итак, давайте расширим наш маленький сервер Go (или посмотрите ветку mutate, если используете код из моего github).

Нам нужно добавить переменную для хранения наших изменяющихся данных. Да, глобальная переменная - не лучшая практика, но это всего лишь пример кода. Добавьте строку latestPost (дополнительный код для контекста).

Найдите, где мы возвращаем latestPost в запросе, и обновите его, чтобы вместо этого вернуть новую переменную.

Обновите функцию main, чтобы сохранить значение по умолчанию для latestPost.

Наконец, мы создадим нашу мутацию и добавим ее в нашу схему.

Как видите, это довольно просто. Мы берем аргумент для нового значения и просто устанавливаем его, а затем возвращаем это значение latestPost, как обычно в запросе (это стандартная практика для упрощения обновлений на стороне клиента).

Итак, чтобы на самом деле изменить это значение, запустите браузер и укажите его на своем сервере, чтобы открыть игровую площадку, и введите следующее.

Все те же правила запросов по-прежнему применяются, как и имена ваших запросов, но это все, что нужно сделать.

В заключительной части этой серии мы рассмотрим создание базового клиента для чтения с помощью Apollo в JavaScript.