Сервис-функции
Сервис-функции (services) - это хранимые процедуры, реализующие бизнес-логику решения и доступные для вызова извне. В TDG такие процедуры представляют собой функции на языке Lua.
Чтобы добавить в TDG вызываемый сервис, нужно:
- Задать конфигурацию сервиса в формате YAML: его имя, аргументы вызова, возвращаемое значение.
- Реализовать необходимую логику на языке Lua с использованием Lua API TDG.
- Загрузить файлы с исходным кодом и конфигурацией сервиса в TDG.
После этого TDG автоматически сгенерирует API для вызова сервиса через GraphQL, REST API и iproto (бинарный протокол Tarantool).
В этом руководстве рассмотрим пример создания нового сервиса в TDG и способы его вызова.
Для выполнения примера требуются:
- настроенный кластер TDG;
- модель данных, сохраненная в файле
model.avsc. В примере используется модель из раздела по настройке модели данных; - HTTP-клиент, например, curl.
Пример сервиса будет возвращать список всех городов страны, загруженных в хранилище, по её имени.
Руководство включает в себя следующие шаги:
Чтобы добавить в TDG сервис, необходимо добавить
соответствующую секцию в
конфигурацию TDG.
Сервисы можно описывать либо в общем конфигурационном файле (секция
services в файле config.yml), либо в отдельном файле services.yml.
Конфигурация сервиса включает такие параметры, как его уникальное имя, вызываемая функция, аргументы вызова, тип возвращаемого значения и другие. Полная информация о параметрах конфигурации сервисов приведена в справочнике по конфигурации бизнес-логики.
Пример минимальной конфигурации сервиса без аргументов:
# config.ymlservices:hello_world:doc: "Hello World script"function: hello.helloreturn_type: string
Создадим конфигурацию сервиса для получения всех городов по названию страны:
# config.ymlservices:get_cities:doc: "Get cities by country name"function: cities.get_citiesreturn_type: {"type":"array", "items":"City"}args:country: stringtypes:__file: model.avsc
Эта конфигурация задаёт следующее поведение:
- Сервис будет доступен для вызова через GraphQL по имени
get_citiesи через REST API по адресуhttp://localhost:8081/service/get_cities; - При вызове будет выполняться функция
get_citiesиз файлаcities.lua; - Сервис будет возвращать массив объектов пользовательского типа
City; - Сервис будет принимать один строковый аргумент - название страны.
Как указано в конфигурации сервиса, его код должен храниться в файле
cities.lua в функции get_cities. Этот файл может выглядеть следующим
образом:
– cities.lualocal repository = require('repository')local log = require('log')local json = require('json')function get_cities(arg)log.info('Getting cities of: %s', json.encode(arg))local result = repository.find("City", {{'country', '==', arg["country"]}})return resultendreturn {get_cities = get_cities}
Все аргументы сервиса передаются в первый аргумент функции в виде
Lua-таблицы. Ключами в этой таблице являются имена аргументов,
объявленные в конфигурации сервиса. Таким образом, для обращения к
конкретному аргументу необходимо получить элемент таблицы по имени из
конфигурации сервиса, например, arg["country"].
TDG предоставляет набор Lua-модулей для реализации бизнес-логики. Набор включает как модули для работы с хранилищем Tarantool и подсистемами TDG, так и модули для работы с распространёнными технологиями, такими как различные СУБД или JSON.
В этом примере используются модули:
repository- интерфейс репозитория TDG. Содержит функции для работы с данными в хранилище Tarantool. В примере используется repository.find для поиска подходящих объектов типаCity.log- запись в журнал TDG. В примере используетсяlog.infoдля записи в журнал информации о вызовах сервиса.json- работа с JSON. В примере используетсяjson.encodeдля формирования строкового JSON представления переданного аргумента.
Чтобы выполнить пример, нужно загрузить архив с моделью данных, файлом конфигурации и функцией сервиса в TDG:
- Поместите Lua-файл с кодом сервиса в папку
src. - Упакуйте в zip-архив:
- папку
src, внутри которой лежит файл с кодом сервиса; - модель данных
model.avsc; - файл конфигурации
config.yml.
- папку
- Загрузите архив в TDG согласно инструкции.
Чтобы вызвать сервис через GraphQL, укажите в запросе имя сервиса и
аргументы в формате name:value:
query {get_cities(country: "Germany")}
Как и в случае запросов к данным, GraphQL позволяет получать отдельные поля возвращаемых объектов:
query {get_cities(country: "Germany") {title,capital}}
Ответ:
{"data": {"get_cities": [{"title": "Berlin","capital": true},{"title": "Dresden","capital": false},{"title": "Munich","capital": false}]}}
Сервисы доступны для вызова через REST API на HTTP-адресах (endpoint)
вида /service/<service_name>. Для вызова сервисов используются
POST-запросы.
Для вызова сервиса без аргументов отправьте POST-запрос на соответствующий адрес, например:
curl -X POST http://localhost:8081/service/hello_world
Если у сервиса есть аргументы, передайте их одним из двух способов:
-
в параметрах запроса с соответствующими именами:
curl -X POST http://localhost:8081/service/get_cities?country=Russia -
в теле запроса в формате JSON:
curl -d '{"country":"Russia"}' -H "Content-Type: application/json" \-X POST http://localhost:8081/service/get_cities
Ответ:
{"result": [{"cursor": "gaRzY2FukqZSdXNzaWGmTW9zY293","country": "Russia","title": "Moscow","population": 12655050,"postcodes": [101000,119021,115035,109028,109004],"capital": true},{"cursor": "gaRzY2FukqZSdXNzaWGwU2FpbnQgUGV0ZXJzYnVyZw","country": "Russia","title": "Saint Petersburg","population": 5384342,"postcodes": [191193,191040,195275,983002,983015],"capital": false},{"cursor": "gaRzY2FukqZSdXNzaWGkVHZlcg","country": "Russia","title": "Tver","population": 424969,"postcodes": [170006,170100,170037,170028],"capital": false}]}
Полная информация о REST API сервисов TDG приведена в справочнике по REST API.