Сервис-функции¶
Сервис-функции (services) – это хранимые процедуры, реализующие бизнес-логику решения и доступные для вызова извне. В TDG такие процедуры представляют собой функции на языке Lua.
Чтобы добавить в TDG вызываемый сервис, нужно:
Задать конфигурацию сервиса в формате YAML: его имя, аргументы вызова, возвращаемое значение.
Реализовать необходимую логику на языке Lua с использованием Lua API TDG.
Загрузить файлы с исходным кодом и конфигурацией сервиса в TDG.
После этого TDG автоматически сгенерирует API для вызова сервиса через GraphQL, REST API и iproto (бинарный протокол Tarantool).
В этом руководстве рассмотрим пример создания нового сервиса в TDG и способы его вызова.
Для выполнения примера требуются:
модель данных, сохраненная в файле
model.avsc
. В примере используется модель из раздела по настройке модели данных;HTTP-клиент, например, curl.
Пример сервиса будет возвращать список всех городов страны, загруженных в хранилище, по её имени.
Руководство включает в себя следующие шаги:
Подготовка конфигурации сервиса¶
Чтобы добавить в TDG сервис, необходимо добавить соответствующую
секцию в конфигурацию TDG. Сервисы можно описывать
либо в общем конфигурационном файле (секция services
в файле config.yml
),
либо в отдельном файле services.yml
.
Конфигурация сервиса включает такие параметры, как его уникальное имя, вызываемая функция, аргументы вызова, тип возвращаемого значения и другие. Полная информация о параметрах конфигурации сервисов приведена в справочнике по конфигурации бизнес-логики.
Пример минимальной конфигурации сервиса без аргументов:
# config.yml
services:
hello_world:
doc: "Hello World script"
function: hello.hello
return_type: string
Создадим конфигурацию сервиса для получения всех городов по названию страны:
# config.yml
services:
get_cities:
doc: "Get cities by country name"
function: cities.get_cities
return_type: {"type":"array", "items":"City"}
args:
country: string
types:
__file: model.avsc
Эта конфигурация задаёт следующее поведение:
Сервис будет доступен для вызова через GraphQL по имени
get_cities
и через REST API по адресуhttp://localhost:8081/service/get_cities
;При вызове будет выполняться функция
get_cities
из файлаcities.lua
;Сервис будет возвращать массив объектов пользовательского типа
City
;Сервис будет принимать один строковый аргумент – название страны.
Реализация логики на Lua¶
Как указано в конфигурации сервиса, его код должен храниться в файле cities.lua
в функции get_cities
. Этот файл может выглядеть следующим образом:
-- cities.lua
local 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 result
end
return {
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¶
Чтобы вызвать сервис через 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¶
Сервисы доступны для вызова через 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.