Учитывая все безумие, которое в настоящее время происходит в мире API с GraphQL , вы можете задаться вопросом, как перенести существующие API REST в GraphQL, ничего не нарушая. Это руководство поможет вам выполнить миссию REST to GraphQL без изменения базы кода, чтобы вы могли выполнить REST с GraphQL (каламбур)!
ОТДЫХ на GraphQL
Ну, сторонники GraphQL уже проделали большую работу по маркетингу GraphQL . Уважая их усилия, я не буду вдаваться в подробности, но приведу резюме:
- GraphQL позволяет получать несколько ресурсов за один запрос.
- GraphQL решает проблему чрезмерной загрузки REST, позволяя вам описать ваши точные потребности в данных.
- GraphQL помогает вам решить проблему N + 1 запросов во внешнем интерфейсе, выбирая связанные данные в одном запросе.
Вместо этого в этом руководстве я затрону тот аспект, который большинство людей упускают при защите GraphQL, а именно: «Мы уже вложили значительные средства в REST». Это означает:
- Большинство наших существующих услуг находятся в REST
- Нам удобнее писать REST услуги
- Мы хотим поддерживать существующих клиентов, используя REST API
Хотя многие статьи помогают вам перейти с REST на GraphQL, все они заставляют вас изменить существующую кодовую базу или написать новую перед вашими REST-сервисами.
Вы также можете подумать: зачем и когда использовать GraphQL
Но ждать…
Если это работает, то не трогай это.
Разве это не было первым правилом программирования?
Миграции могут быть болезненными, особенно масштабы огромного кода могут быть пугающими. Всегда есть шанс что-то сломать.
Почему мы не можем просто отдохнуть?
Посмотрим правде в глаза, мы все ленивы по своей природе. Мы любим простые взломы и простые решения.
Что, если бы был способ, которым вы могли бы сохранить свои службы REST как есть и при этом по-прежнему получать слой GraphQL поверх него без какого-либо написания кода? Звучит как магия, верно? Что ж, Space Cloud помогает сделать это возможным.
Что такое космическое облако?
Для простоты Space Cloud — это веб-сервер с открытым исходным кодом, который предоставляет мгновенные API GraphQL и REST для вашей базы данных и микросервисов.
Самое классное в Space Cloud — это то, что все API работают в реальном времени. При желании вы можете подписаться на изменения в базе данных. Эта функциональность пригодится при создании приложений в реальном времени.
Однако в этом руководстве мы будем использовать remote service
модуль Space Cloud для переноса ваших REST-сервисов в GraphQL.
Архитектура
Вот как выглядит окончательная архитектура GraphQL поверх REST:
Ваши приложения отправляют запрос GraphQL в Space Cloud, который, в свою очередь, попадает в конечную точку REST на вашем сервере. В этом случае Space Cloud выступает в качестве прокси-сервера GraphQL или шлюза API.
Как вы могли заметить, Space Cloud — это отдельный слой GraphQL, расположенный поверх ваших REST-сервисов. Прелесть этого факта в том, что ваши REST-сервисы все еще не повреждены , и вы можете использовать их непосредственно в существующих клиентах. Этот факт позволяет вам отправлять REST-сервис в GraphQL, не ломая старых клиентов.
Большой! Мы поняли, что такое Space Cloud и как оно работает с нашим приложением. Давайте перейдем прямо к действию!
Что мы будем строить
В этом руководстве мы будем создавать простой арифметический сервис, который имеет следующие конечные точки:
- Конечная точка сумматора:
POST
/adder
- Конечная точка удвоителя:
GET
/doubler/:num
Конечная точка сумматора вернет сумму двух чисел, полученную по запросу body
. Конечная точка удвоителя, с другой стороны, вернет двойное число, полученное в качестве URL path parameter
.
Большой! Давайте начнем строить вещи сейчас!
Примечание: не беспокойтесь, если вы застряли где-нибудь. Вы всегда можете пропинговать меня на этом сервере Discord , и я помогу вам лично.
Шаг 1: Написание службы
Примечание. Даже если вы сейчас читаете это со своего мобильного телефона, вы все равно можете следовать этому руководству, просто читая.
Давайте начнем с написания нашего сервиса REST. Мы собираемся написать наш REST-сервис в NodeJS, используя Express.
Примечание. Вы можете написать свою службу на любом языке или в любой среде, если она поддерживает HTTP, поскольку именно этот протокол Space Cloud будет использовать для связи с вашей службой REST.
Сначала создайте папку, которая будет служить нашим рабочим каталогом.
Создать проект NPM:
Джава
xxxxxxxxxx
1
npm init -y
Установите Экспресс:
Джава
xxxxxxxxxx
1
npm install --save express
Написать экспресс-сервер
Создайте файл index.js
и скопируйте и вставьте следующий код:
Джава
xxxxxxxxxx
1
var express = require("express");
2
var app = express();
3
4
app.use(express.json());
5
6
app.post("/adder", function(req, res) {
7
const num1 = req.body.num1;
8
const num2 = req.body.num2;
9
const response = { result: num1 + num2 };
10
res.status(200).send(JSON.stringify(response));
11
});
12
13
app.get("/doubler/:num", function(req, res) {
14
const num = req.params.num;
15
const response = { result: num * 2 };
16
res.status(200).send(JSON.stringify(response));
17
});
18
19
var server = app.listen(5000, function () {
20
console.log("app running on port:", server.address().port);
21
});
22
Как видите, код довольно прост. Мы только что создали HTTP-сервер, использующий ExpressJS, который прослушивает порт 5000.
Сервер имеет две конечные точки, как мы обсуждали ранее:
- Конечная точка сумматора: мы ожидаем получить два числа —
num1
иnum2
отPOST
тела. Все, что мы делаем, это возвращаем сумму этих двух чисел. - Конечная точка удвоителя: мы просто возвращаем число, которое мы получаем от
URL path parameter
.
Это все, что нам нужно написать для этого сервиса.
Примечание. Для переноса существующих служб REST вам не нужно писать / изменять код. И если ваши службы уже запущены, вы можете пропустить следующий шаг.
Шаг 2: Запустите Сервис
Просто запустите следующую команду для запуска сервиса:
Джава
xxxxxxxxxx
1
node index.js
Большой! Наша служба REST запущена и работает. Давайте запустим Space Cloud и воспользуемся этим REST-сервисом через GraphQL.
Шаг 3: Скачать Space Cloud
Вам необходимо скачать двоичный файл Space Cloud для вашей операционной системы, или вы можете создать его непосредственно из исходного кода. Вам нужно иметь версию 1.13.0 или выше, чтобы собрать ее из исходного кода.
Загрузите бинарный файл для вашей ОС здесь:
Вы можете распаковать сжатый архив.
Для Linux / Mac: unzip space-cloud.zip && chmod +x space-cloud
Для Windows: щелкните правой кнопкой мыши по архиву и выберите extract here
.
Чтобы убедиться, что двоичный файл правильный, введите следующую команду из каталога, куда загружен двоичный файл:
Для Linux / Mac: ./space-cloud -v
Для Windows: space-cloud.exe -v
Это должно показать что-то вроде этого:
Джава
xxxxxxxxxx
1
space-cloud-ee version 0.13.0
Шаг 4: Запустите Space Cloud
Чтобы запустить Space Cloud в dev
режиме, скопируйте и вставьте следующую команду и нажмите Enter:
Для Linux / Mac: ./space-cloud run --dev
Для Windows: space-cloud.exe run --dev
Вы должны увидеть что-то вроде этого при запуске Space Cloud:
Джава
xxxxxxxxxx
1
Creating a new server with id auto-1T5fA9E1B2jeNUbV8R0fOPubRng
2
Starting http server on port: 4122
3
4
Hosting mission control on http://localhost:4122/mission-control/
5
6
Space cloud is running on the specified ports :D
Примечание .
--dev
Флаг указывает Space Cloud на запуск в режиме разработки (чтобы пользовательский интерфейс администратора не запрашивал имя пользователя и пароль)
Шаг 5: Настройте космическое облако
Как вы могли заметить, Space Cloud создает config.yaml
файл в рабочем каталоге.
Space Cloud нужен этот файл конфигурации для работы. Файл конфигурации используется для загрузки такой информации, как REST-серверы для подключения и их конечные точки.
Space Cloud имеет свой собственный Mission Control (интерфейс администратора) для быстрой настройки всего этого.
Открытый контроль полетов
Перейдите по адресу http: // localhost: 4122 / mission-control, чтобы открыть Mission Control.
Примечание: замените
localhost
адрес вашего Space Cloud, если вы не используете его локально.
Создать проект
Нажмите на Create a Project
кнопку, чтобы открыть следующий экран:
Дайте name
вашему проекту.
Неважно, какую базу данных вы выберете здесь, так как мы все равно не будем ее использовать.
Нажмите, Next
чтобы создать проект.
Шаг 6. Добавление удаленного сервиса в Space Cloud
Перейдите в Remote Services
раздел «Управление полетами».
Нажмите на Add first remote service
кнопку, чтобы открыть следующую форму:
Введите имя службы как arithmetic
и URL службы как:
http://localhost:5000
После того, как вы добавили удаленный сервис, вы сможете увидеть его в таблице удаленных сервисов:
Нажмите на View
кнопку в столбце Действия, чтобы открыть страницу сервиса.
Нажмите на Add first remote endpoint
кнопку, чтобы открыть следующую форму:
Поместите следующую конечную точку сумматора:
- Название:
adder
- Метод:
POST
- Путь:
/adder
Еще раз нажмите на Add
кнопку, чтобы добавить doubler
конечную точку:
- Название:
doubler
- Метод:
GET
- Путь:
/doubler/{args.num}
Примечание: не беспокойтесь о
{args.num}
части сейчас. Просто убедитесь, что вы поставили Метод какGET
.
Шаг 7: Запрос сервиса REST через GraphQL
Мы добавили нашу службу REST и две конечные точки в Space Cloud. Пришло время сделать запрос, используя наш унифицированный API-интерфейс GraphQL.
Направляйтесь в Explorer
раздел:
Попробуйте выполнить следующий запрос GraphQL в обозревателе GraphiQL:
Джава
xxxxxxxxxx
1
{
2
adder(num1: 10, num2: 20) {
3
result
4
}
5
}
Вы должны увидеть ответ вроде этого:
Джава
xxxxxxxxxx
1
{
2
"adder": {
3
"result": 30
4
}
5
}
Получив приведенный выше запрос GraphQL, Space Cloud отправила следующий запрос в службу REST:
- Метод:
POST
- Путь:
/adder
- Тело запроса:
Джава
xxxxxxxxxx
1
{
2
"num1": 10,
3
"num2": 20
4
}
Это означает, что аргументы, которые вы передаете в запросе GraphQL, отправляются как тело запроса в службу REST.
Давайте попробуем doubler
запросить конечную точку следующим запросом GraphQL:
Джава
xxxxxxxxxx
1
{
2
doubler(num: 50) {
3
result
4
}
5
}
Этот запрос GraphQL переводится SC в вызов REST следующим образом:
Джава
xxxxxxxxxx
1
GET /doubler/50
Если вы помните, конечная точка, которую мы добавили в Space Cloud для удвоителя, была:
Джава
xxxxxxxxxx
1
/doubler/{args.num}
Основываясь на этой конечной точке, Space Cloud понимает, что ему нужно выбрать аргумент num
из запроса GraphQL и использовать его в качестве переменной для формирования пути /doubler/50
.
При успешном вызове вы должны увидеть такой ответ:
JSON
xxxxxxxxxx
1
{
2
"doubler": {
3
"result": 100
4
}
5
}
Бонус — Сервисная Цепочка
Следуя этому руководству до тех пор, пока здесь успешно, мы все заслуживаем заслуженного бонуса! Давайте посмотрим, как этот переход от REST к GraphQL открывает для нас невероятную мощь Service Chaining.
Давайте рассмотрим сценарий, в котором:
- Мы хотим сложить два числа, используя услугу сумматора.
- Удвойте результат, который мы получили от сервиса сумматоров.
ПУТЬ ОТДЫХА
Если бы мы использовали REST в нашем клиентском коде, вышеприведенная задача выглядела бы так:
Обратите внимание, как мы делаем два запроса от внешнего интерфейса, что означает удвоение времени в оба конца . Это приводит к медленному времени отклика и плохому опыту пользователя.
GraphQL Way
Теперь, если мы переключили клиент с REST на GraphQL с помощью Space Cloud, наши запросы будут выглядеть так:
Notice, here we are making only one GraphQL query from the frontend to the backend (Space Cloud). Space Cloud, in turn, is making two requests to your REST server to fulfil this request. However, the round trips of these requests (from Space Cloud to your server) are negligible as they are in the same network.
The GraphQL query to Space Cloud to achieve the above task will be:
xxxxxxxxxx
{
adder(num1: 10, num2: 20) @arithmetic {
doubler(num: "adder.result") @arithmetic {
result
}
}
}
Notice, how we are calling the doubler
service after the response of adder
service and passing the result
of adder service to the doubler as an argument.
The response for this query will look like this:
xxxxxxxxxx
{
"adder": {
"doubler": {
"result": 60
}
}
}
As you would have guessed we got 60
as a result ((10 + 20) * 2).
Additional tip: If you wanted to query two unrelated REST services parallelly, you could have done that too in a single request like this:
xxxxxxxxxx
{
adder(num1: 10, num2: 20) @arithmetic {
result
}
doubler(num: 50) @arithmetic {
result
}
}
I will leave the response part of this query to you as an assignment .
Conclusion
First of all, give yourself a pat on the back for having followed this guide to the end.
We learned that:
- Migrating from REST to GraphQL doesn’t require code changes.
- We don’t need to choose between REST and GraphQL. We can support both REST and GraphQL together in the same application.
- Using GraphQL with Space Cloud provides us with some neat networking benefits and helps you reduce your round trips.
Well, there’s a lot more you can do with Space Cloud other than migrating from REST to GraphQL (eg: cross-database joins). Give Space Cloud a star on Github if you like it. Join our Discord server if you wanna bounce off some ideas or have any questions.