Интеграции GraphQL и NodeJS с помощью функций Cloud Code Functions

GraphQL – это сахар, специи и все остальное для разработчиков API, но по сути это язык запросов, позволяющий указать, что именно вы ищете.

А что, если вам нужно больше бизнес-аналитики, чем это в вашем приложении?

Что, если вам нужна логика?

Что, если вам нужен этот аккуратный модуль NPM Module?

Что ж, пристегните ремни, потому что сегодня я покажу вам нечто очень мощное. А с большими возможностями приходит большая… ну… большая экономия времени, большие возможности, много всего хорошего…

Если вы хотите узнать больше о GraphQL, посмотрите этот пост: Что такое GraphQL

Вы должны быть такого роста, чтобы ездить верхом…

Для работы с GraphQL используйте Parse 3.5.0 или более позднюю версию.
Перейдите в Настройки сервера и Управление сервером Parse и убедитесь, что вы используете совместимую версию.

Наша новая блестящая функция: GraphQL + Cloud Code Functions

Если вы уже являетесь пользователем Parse/Back4app, вы, вероятно, использовали или хотя бы слышали о Cloud Code.

Cloud Code – это, по сути, код NodeJS, который запускается с серверов приложений Back4app, а не с конечных устройств.

Это дает несколько ключевых преимуществ в зависимости от ваших потребностей, но в основном это позволяет вам:

  • Экономить заряд батареи мобильного телефона

    Когда вы переносите тяжелую нагрузку по обработке данных с устройства в облако, интенсивная обработка не будет выполняться на устройстве, что позволяет сэкономить заряд батареи. Обработка выполняется на наших серверах, а клиенту передается только конечный результат. Больше никакого горячего телефона в кармане. Больше никаких “OMG, это приложение высасывает мою батарею!”.

  • Экономьте на тарифах на передачу данных

    Итак, у вас есть куча объектов, которые нужно получить, чтобы составить отчет. Тысячи? Миллионы?
    Это очень много данных, которые вы должны получить, и если вы не подключены к WiFi, вам лучше обновить тарифный план сотового телефона.
    Мы все знаем, что тарифный план довольно дорогой (никто больше не платит за SMS-сообщения, верно?), так что, если бы у нас был более умный подход?
    Что, если бы мы могли получить отчет, полностью рассчитанный в облаке, и передать на устройство только самый последний результат? Меньший объем полезной нагрузки, который бы потреблял гораздо меньше данных, а также работал быстрее?
    Звучит потрясающе? Именно это и делает Cloud Code…

  • Ускоренное развертывание кода

    Когда-то разработчикам приходилось заново публиковать свои программы в магазинах App Store. В те времена это было лотереей: если рецензент попадал быстрее, ваше приложение становилось доступным для пользователей в тот же день. Попадись медленный или придирчивый рецензент, и публикация приложения могла занять несколько недель. Если оно было опубликовано.
    Зачем так рисковать?
    Поставляйте в App Store только фронтенд-часть приложения, а как можно больше логики оставляйте в виде облачного кода.
    Нужно внести небольшое изменение в логику? Или внести большое? Нет проблем.
    Измените облачный код, разверните его снова – и вы как новенький. Никаких отзывов от какого-то парня из другого места и мгновенная доступность для ваших клиентов.

Но опять же… как насчет GraphQL?

GraphQL позволяет делать запросы. Вы можете делать очень умные запросы, но это всего лишь запросы.

Когда наш генеральный директор Дэви обсуждал, как сделать его умнее, интеграция с Cloud Code Functions оказалась просто логичной: вы получаете лучшее из обоих миров! Мощь и интеллект Cloud Code Functions, а также простота и удобство поддержки GraphQL.

С помощью нашей новой функции вы можете расширить типы GraphQL для выполнения функций Cloud Code Functions и получения их результатов.

Вы можете применить любую бизнес-логику, которую только можете себе представить, к своим функциям Cloud Code Functions, включить в них модули NPM и запросить все это с помощью GraphQL.

Хватит разговоров. Давайте приступим к работе…

Классы и объекты, которые мы будем использовать

Для этого поста я создал два отдельных класса: Employee и Pet, которые будут содержать сотрудников Back4app и их соответствующих питомцев.

У сотрудника есть следующие свойства:

  • имя (Строка)
  • возраст (Число)
  • электронная почта (Строка)
  • должность (Строка)
  • hasThisPet (указатель на класс Pet)

screen-shot-2019-08-07-at-13-18-26

Питомец обладает следующими свойствами:

  • имя (String)
  • вид (String)

screen-shot-2019-08-07-at-13-18-37

И некоторые функции облачного кода

Для наших функций облачного кода я напишу файл с именем main.js и включу в него следующий код.

Он содержит пять полностью прокомментированных функций облачного кода, которые будут выполнять:

  • checkGraphQLSupport
    проверять, есть ли в приложении поддержка GraphQL
  • retrieveFirstEmployeeByName
    получить все данные о первом найденном в базе данных сотруднике с заданным именем
  • retrieveAllEmployees
    получить все сведения обо всех сотрудниках
  • retrieveOnwerOfPetByName
    получение сведений о сотруднике, у которого есть домашнее животное с заданным именем
  • retrieveEmployeeByNameWithPet
    получение всех сведений о сотруднике и его питомце
Parse.Cloud.define("checkGraphQLSupport", async req => {
  /*
    Эта функция возвращает, есть ли в приложении поддержка GraphQL. 
    Значение parseGraphQLServer равно true, если приложение поддерживает его, или false в противном случае
  */
  if (parseGraphQLServer){
    return "Это приложение имеет поддержку GraphQL";
  } else {
    return "Это приложение не имеет поддержки GraphQL. Возможно, неверная версия Parse?";
  }
});

Parse.Cloud.define("retrieveFirstEmployeeByName", async req => {
  /*
    Эта функция извлекает первого найденного сотрудника с заданным именем.
    При этом извлекаются все свойства сотрудника.
    Возвращается только один сотрудник, если в базе данных их несколько.
    Если сотрудников нет, возвращается null.
  */
  const query = new Parse.Query("Employees"); 
  query.equalTo("name", req.params.name);
  const result = await query.first();
  return result;
});

Parse.Cloud.define("retrieveAllEmployees", async req => {
  /*
    Эта функция извлекает всех сотрудников.
    Получаются все свойства класса Employee, но только этого класса.
    Не извлекаются детали указателей или отношений, только идентификатор объекта.
    Возвращается массив Employees. Пустой, если сотрудников нет.
  */
  const query = new Parse.Query("Employees"); 
  const results = await query.find();
  return results;
});

Parse.Cloud.define("retrieveOnwerOfPetByName", async req => {
  /*
    Эта функция извлекает информацию о сотруднике, связанном с питомцем,
    по имени питомца.
    Извлекаются все свойства класса Employee.
    Никаких подробностей о питомце не будет получено.
    Возвращается массив Pet. Пустой, если не найдено ни одного питомца.
  */

  // Сначала мы создаем запрос для получения информации о питомце
  const petQuery = new Parse.Query("Pet"); 
  petQuery.equalTo("name", req.params.name);
  
  // Затем мы составляем запрос для получения сведений о сотруднике на основе свойства hasThisPet
  let employeeQuery = new Parse.Query("Employees"); 
  employeeQuery.matchesQuery("hasThisPet", petQuery);
  const results = await employeeQuery.find();

  return results;
  
});

Parse.Cloud.define("retrieveEmployeeByNameWithPet", async req => {
  /*
    Эта функция извлекает информацию о сотруднике и его питомце,
    по имени сотрудника.
    Извлекаются все свойства класса Employee и класса Pet.
    Возвращается массив Employee, включая полностью заполненное свойство hasThisPet
    с информацией о питомце.
    Если ни один сотрудник не найден, возвращается массив empy.
  */
  const query = new Parse.Query("Employees"); 
  query.equalTo("name", req.params.name);
  query.include("hasThisPet")
  const results = await query.find();
  return results;
});

Мы загрузим его в нашу папку Cloud Code Functions, в папку Cloud.

Небольшой дополнительный шаг

Функции Cloud Code Functions, которые мы только что опубликовали, теперь можно использовать, но для того чтобы они работали с GraphQL, мы должны создать файл с именем schema.graphql и раскрыть эти функции.

Синтаксис очень прост, но требует внимания:

extend type Query {
 GraphQLMethodName (parameterName: parameterType): ReturnType! @resolve(to:"CloudCodeFunctionName")
}

Для приведенного выше кода синтаксис представляет собой:

  • GraphQLMethodName .
    Это имя, которое вы будете называть в запросе GraphQL. Оно не обязательно должно совпадать с именем функции облачного кода, но вы должны выбрать что-то, что позволяет легко понять, что делает этот метод.
  • parameterName
    Имя параметра, который вы будете использовать в запросе внутри функции облачного кода. Вы можете не передавать это значение, если не используете параметры в своей функции облачного кода.
  • parameterType
    Тип передаваемого параметра. Вы можете узнать больше о схемах и увидеть все возможности. Вы можете не передавать этот параметр, если не используете параметры в своей функции Cloud Code Function.
  • ReturnType
    Это тип возврата вашего метода.
  • CloudCodeFunctionName
    Это имя должно совпадать с именем функции облачного кода, которое вы указали в файле main.js, поскольку метод будет вызывать этот код по имени функции.

Так, для нашего файла main.js, который мы только что создали, наш schema.graphql будет иметь следующий вид:

extend type Query {
  checkGraphQLSupport: String! @resolve(to: "checkGraphQLSupport")
  retrieveThisEmployeeByName (name:String): EmployeesClass! @resolve(to: "retrieveFirstEmployeeByName")
  giveMeAllEmployees: [EmployeesClass!]! @resolve(to: "retrieveAllEmployees")
  whichEmployeeIsOnwerOfThisPet (name:String): [EmployeesClass!]! @resolve(to: "retrieveOnwerOfPetByName")
  gatherEmployeeAndPetByEmployeeName (name:String): [EmployeesClass!]! @resolve(to: "retrieveEmployeeByNameWithPet")
}

Не так уж и сложно, правда?

Заметьте, я использовал очень обширные имена, которые не совпадают с именами функций Cloud Code Functions, просто чтобы вы знали, что их можно переименовать при экспонировании.

Теперь вернитесь в раздел Cloud Code Functions вашего приложения и загрузите этот файл. Убедитесь, что он также находится в папке Cloud. При необходимости вы можете перетащить его туда.
Если у вас уже есть файл с таким именем и вы не можете загрузить новый, вы можете щелкнуть его правой кнопкой мыши и удалить перед загрузкой.

Разверните все, и мы готовы к работе:

screen-shot-2019-08-07-at-14-52-49

Настало время для волшебства…

Перейдите в консоль GraphQL. Начните вводить “query” и используйте функцию автозаполнения (CTRL + Spacebar на Windows, OPTION + Spacebar на Mac), и увидите, как происходит волшебство:

screen-shot-2019-08-07-at-15-11-36

Все наши методы на месте, и мы можем запросить каждый из них. Давайте попробуем сделать это по очереди:

  • checkGraphQLSupport

    (переходит к нашей функции облачного кода checkGraphQLSupport)
    screen-shot-2019-08-07-at-15-14-49

  • retrieveThisEmployeeByName (name:String)

    (обращается к нашей функции облачного кода retrieveFirstEmployeeByName)
    screen-shot-2019-08-07-at-15-19-18

  • giveMeAllEmployees

    (обращается к нашей функции облачного кода retrieveAllEmployees)
    screen-shot-2019-08-07-at-15-21-06
    Обратите внимание, что в примере выше свойства name и age были получены правильно, но в hasThisPet имя и вид питомца имеют нулевые значения.
    Это связано с тем, что в этой функции облачного кода мы не включили (с помощью метода include()) информацию о питомце.
    Автозаполнение покажет нам возможные варианты, но в функции облачного кода не было предоставлено данных для заполнения этой информации.
    Как включить информацию, смотрите в примере gatherEmployeeAndPetByEmployeeNameresolves ниже.

  • whichEmployeeIsOnwerOfThisPet

    (разрешается нашей функцией облачного кода retrieveOnwerOfPetByName)
    screen-shot-2019-08-07-at-15-26-12

  • gatherEmployeeAndPetByEmployeeName 

    (решается нашей функцией облачного кода retrieveEmployeeByNameWithPet)
    screen-shot-2019-08-07-at-15-28-54

Ваши замечательные определения были обновлены

Вот так можно привнести бизнес-логику в GraphQL.

Люблю тебя, 3000!

Заключение

GraphQL – это мощный и простой многоплатформенный язык запросов и среда выполнения, но в конечном итоге это только язык запросов.
Благодаря новой интеграции с Cloud Code Functions мы получили лучшее из двух миров, раскрыв всю мощь Cloud Code (включая NPM Modules, детка!).

Теперь все зависит от вас и вашей креативности! Дайте нам знать, как вам это нравится и как вы используете это в своих проектах, в комментариях ниже!

Что такое Cloud Code?

Облачный код — это, по сути, Node JS. Он работает с серверов Back4app, а не с конечных устройств. Он имеет различные преимущества в зависимости от ваших потребностей. Он позволяет вам экономить батареи, быстрее развертывать код и сохранять данные в соответствии с вашими потребностями.

Как Cloud Code помогает экономить заряд батареи мобильного телефона?

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

Как Cloud Code помогает экономить данные?

Сам облачный код извлечет все данные, которые вы делали с помощью Wi-Fi или мобильных данных. Он продолжит повторно извлекать данные и рассчитывать полные отчеты в облаке. Он извлечет только последний результат на устройство, что приведет к меньшей полезной нагрузке и меньшему использованию данных.


Leave a reply

Your email address will not be published.