Дерево страниц

SAYMON документация

Перейти к концу метаданных
Переход к началу метаданных

В этом разделе, в качестве примера серверного модуля, мы рассмотрим разработку актора, реализующего доступ к данным по объектам SAYMON через GraphQL API.

Шаг 1: Заготовка

Первым шагом будет создание класса для нашего актора:

class GraphQlActor {
  initialize(selfActor) { // Этот метод вызовется при инициализации актора.
    // Пишем сообщение в лог с уровнем Info.
    selfActor.getLog().info('GraphQl actor launched!');
  }

  destroy() { // Этот метод вызовется при уничтожении актора.
  }
}

module.exports = GraphQlActor;

Сохраним код выше в файл /tmp/saymon-modules/graphql-actor.js и пропишем директорию этого файла в качестве директории-источника пользовательских расширений в конфигурацию SAYMON сервера:

{
  ...,
  "server": {
    ...,
    "extension_path": "/tmp/saymon-modules"
  },
  ...
}

После того, как мы сделали это и перезапустили SAYMON сервер, в логе мы увидим:

Thu Dec 20 2018 13:06:35 GMT+0300 - info: InMemoryActor(5c1b69ab98b8e722e14d6b23, GraphQlActor): GraphQl actor launched!

Шаг 2: Тестовый запрос

Следующий наш шаг: запустить GraphQL-сервер с тестовым запросом.

Для этого, в первую очередь, нам необходимо установить модули для работы с GraphQL. В директории нашего расширения (/tmp/saymon-modules/graphql-actor.js) выполним команды для установки модулей:

$ npm install apollo-server
$ npm install graphql

После этого в нашей директории появится папка node_modules с необходимыми модулями.

Теперь реализуем GraphQL сервер с простейшей схемой:

const apollo = require('apollo-server');

class GraphQlActor {
  initialize(selfActor) {
    // Сохраняем логгер актора в переменную для дальнейшего использования.
    const log = selfActor.getLog();

    // Декларируем GraphQL схему для нашего запроса ("info").
    const typeDefs =
      `
      type Query {
        info: String!
      }
      schema {
        query: Query
      }`;

    // Декларируем резолвер для запроса "info": он будет отвечать
    // статическим текстовым сообщением.
    const resolvers = {
      Query: {
        info: () => 'Hello from GraphQL!'
      }
    };

    // Создаём экземпляр GraphQL сервера с передачей туда
    // настроек, определённых выше.
    this.server = new apollo.ApolloServer({
      schema: apollo.makeExecutableSchema({ typeDefs, resolvers })
    });

    // Запускаем сервер на порту по-умолчанию (4000).
    // Это асинхронная операция. Когда она завершится - наш актор
    // готов к работе.
    return this.server.listen().then(({ url }) => {
      log.info(`GraphQL server listening at ${url}`);
    });
  }

  destroy() {
    // Останавливаем GraphQL сервер.
    return this.server && this.server.stop();
  }
}

module.exports = GraphQlActor;

Сохраняем файл, перезапускаем сервер. В логе мы должны увидеть сообщение вида:

Thu Dec 20 2018 13:33:21 GMT+0300 - info: InMemoryActor(5c1b6ff10027fb2d2a588c2d, GraphQlActor): GraphQL server listening at http://localhost:4000/

Если мы перейдём по указанному URL (http://localhost:4000/), в браузере откроется интерфейс для отправки GraphQL-запросов нашему серверу. В нём мы можем отправить запрос "info" и получить тот ответ, который возвращает наш резолвер:

Шаг 3: Выдача данных по объектам SAYMON

Для того, чтобы выдать через API GraphQL данные по объектам SAYMON, мы воспользуемся SAYMON Object API - это внутреннее API, используемое в большинстве компонент SAYMON сервера. Доступ к этому API мы получаем через механизм инъекции зависимостей библиотеки Comedy. Затем, мы декларируем запрос "objects" в GraphQL-схеме - он будет отдавать список всех объектов SAYMON -  и реализуем его в резолвере, который использует SAYMON Object API. Код нашего актора претерпит незначительные изменения:

const apollo = require('apollo-server');

class GraphQlActor {
  // Объявляем, что актору нужен экземпляр SAYMON API.
  static inject() {
    return ['api'];
  }

  // Экземпляр SAYMON API будет передан в конструктор актора.
  constructor(saymonApi) {
    // Сохраняем ссылку на SAYMON API в поле класса.
    this.api = saymonApi;
  }

  initialize(selfActor) {
    // Сохраняем логгер актора в переменную для дальнейшего использования.
    const log = selfActor.getLog();

    // Декларируем GraphQL схему для наших запросов.
    const typeDefs =
      `
      type Object {
        id: ID!
        name: String!
      }
      type Query {
        # Тестовый зарос.
        info: String!
        
        # Возвращает все объекты SAYMON.
        objects: [Object]!
      }
      schema {
        query: Query
      }`;

    // Декларируем резолверы.
    const resolvers = {
      Query: {
        // Резолвер для тестового запроса ("info").
        info: () => 'Hello from GraphQL!',
        
        // Резолвер для запроса, возвращающего все объекты SAYMON ("objects").
        objects: () => {
          // Здесь мы используем SAYMON Object API для получения необходимых данных.
          return this.api.SaymonObject.collection(this.api)
            .map(obj => obj.getBody());
        }
      }
    };

    // Создаём экземпляр GraphQL сервера с передачей туда
    // настроек, определённых выше.
    this.server = new apollo.ApolloServer({
      schema: apollo.makeExecutableSchema({ typeDefs, resolvers })
    });

    // Запускаем сервер на порту по-умолчанию (4000).
    // Это асинхронная операция. Когда она завершится - наш актор
    // готов к работе.
    return this.server.listen().then(({ url }) => {
      log.info(`GraphQL server listening at ${url}`);
    });
  }

  destroy() {
    // Останавливаем GraphQL сервер.
    return this.server && this.server.stop();
  }
}

module.exports = GraphQlActor;

После того, как мы перезапустим сервер, мы сможем получать информацию по объектам SAYMON с помощью запроса "objects":

  • Нет меток