Запросы к данным через REST API¶
В этом разделе описано взаимодействие с хранилищем TDG через REST API. Здесь вы найдёте примеры HTTP-запросов для распространённых сценариев работы с данными. Полное описание REST API TDG приведено в справочнике по REST API.
Подготовка данных¶
В этом руководстве используется модель из раздела по настройке модели данных:
HTTP-адреса REST API¶
Для работы с данными через REST API TDG предоставляет HTTP-адреса (endpoints)
вида /data/<TypeName>
для типов, объявленных в модели данных.
Например, http://localhost:8081/data/City
.
Авторизация¶
Для авторизации по REST API используется процедура авторизации HTTP-запроса по токену приложений. Для подробностей обратитесь к разделу Авторизация и отправка HTTP-запросов.
Запросы данных¶
Для получения данных определённого типа через REST API используются GET-запросы.
Через REST API можно выбирать данные по индексам со условиями поиска:
совпадение;
сравнение: больше, больше или равно, меньше, меньше или равно;
совпадение строки с шаблоном (учётом или без учёта регистра);
условие выбора версий для типов, поддерживающих версионирование.
Условия выбора объектов по индексам передаются в HTTP параметрах запроса вида:
<index_name>=<value>
для поиска по полному совпадению;<index_name>_<condition>=<value>
для поиска по условию. Здесь<condition>
– постфикс, определяющий оператор сравнения, например,_ge
для условия “больше или равно”,like
для проверки соответствия строки шаблону.
Полный список доступных параметров приведён в справочнике по REST API.
Рассмотрим реализацию некоторых популярных сценариев доступа к данным через REST API.
Точечный запрос объекта¶
Точечные запросы предполагают получение одного объекта по уникальному
индексу. Для выполнения точечного запроса по полному совпадению достаточно
выполнить один GET-запрос с параметром <index_name>=<value>
, например,
title_index=Berlin
:
curl http://localhost:8081/data/City?title_index=Berlin
Note
Использование имён индексов, отличных от имён полей, позволяет точно знать, по какому индексу выполняется запрос и оптимизировать работу с данными за счёт этого.
Пакетная обработка¶
В случае выполнения запросов с неизвестным количеством результатов необходимо учитывать пагинацию – постраничную разбивку возвращаемых объектов. По умолчанию размер одной страницы равен 10. Это значит, что ответ на один запрос с условиями будет содержать максимум 10 записей, даже если подходящих объектов больше.
Если вы заранее знаете, сколько объектов хотите получить, вы можете изменить объём
страницы с помощью параметра first
. Например, получить 25 объектов, подходящих
под условие выбора:
curl http://localhost:8081/data/City?population_ge=100000&first=25
Если количество результатов заранее неизвестно, нужно реализовать пакетную обработку (batching) с использованием курсоров. Курсоры позволяют задать начальный объект страницы.
Например, для получения всех объектов типа необходимо выполнять запросы в цикле
с указанием параметра after
- курсора последнего элемента, полученного в предыдущем запросе.
Скрипт для выполнения такого цикла может выглядеть следующим образом:
while true; do
url="http://127.0.0.1:8181/data/City?first=25"
if [[ -n "$cursor" ]]; then
url=$url"&after=$cursor"
fi
res=$(curl -s --url $url)
if [[ $res == "[]" ]]; then break; fi
len=$(echo $res | jq length)
echo $len
cursor=$(echo $res | jq ".[$len - 1].cursor")
done
Порядок возврата результатов¶
Порядок возврата результатов определяется индексом, используемым для выбора объектов, и условием выбора:
“меньше” и “меньше или равно” – по убыванию индекса
“больше” и “больше или равно” – по возрастанию индекса
Если индекс не указан (в запросе нет условий выбора), используется первичный индекс.
Объекты можно запросить в порядке возрастания любого из доступных индексов.
Для этого используется параметр indexed_by=<index_name>
:
curl http://localhost:8081/data/City?indexed_by=population&first=25
Note
Параметр indexed_by
работает только при отсутствии условий выбора объектов.
Если в запросе используется другой индекс для выбора объектов, условие
indexed_by
игнорируется.
Использование составных индексов¶
Если необходима фильтрация объектов по одному полю и сортировка по другому, рекомендуется использовать составной индекс, содержащий оба этих поля.
Пример: есть тип данных с полями типа string
и datetime
. Например, “событие”:
у него есть дата и время (datetime
) и идентификатор объекта, с которым произошло
событие (string
).
Допустим, нужно получить все события, произошедшие с выбранным объектом, по убыванию даты.
Для этого нужен составной индекс, включающий оба поля (object_datetime_index
).
Использовать этот индекс для поиска по полному совпадению не получится, поскольку
изначально известен только идентификатор объекта, но не дата.
Поэтому нужно выполнять поиск по условию “меньше или равно” с указанием только
идентификатора объекта:
curl http://localhost:8081/data/Events?object_datetime_index_le="object_id"
Note
При необходимости используйте параметры first
, after
и пакетную обработку
для получения нужного количества объектов.
В этом случае объекты будут фильтроваться только по идентификатору, без условий выбора даты. Но оператор сравнения “меньше или равно” применяется и к дате, поэтому результаты будут упорядочены по её убыванию.
При этом результат будет содержать лишние объекты с идентификаторами меньше указанного. Такие объекты нужно отсеять, отфильтровав массив полученных результатов в коде приложения.
Вставка данных¶
Для вставки данных определённого типа через REST API используются POST-запросы.
Тело POST-запроса должно содержать добавляемый объект в формате JSON.
Пример вызова curl для вставки объекта:
curl --request POST \
--url 'http://localhost:8081/data/City' \
--data '{"title": "Stuttgart","population": 623738,"country":"Germany","capital":false}'
В результате такого запроса возвращается вставленный объект в формате JSON.
Для ускорения работы можно добавить параметр skip_result=true
: в этом случае
тело ответа будет пустым.
curl --request POST \
--url 'http://localhost:8081/data/City?skip_result=true' \
--data '{"title": "Stuttgart","population": 623738,"country":"Germany","capital":false}'
Изменение данных¶
Для модификации данных определённого типа через REST API используются PUT-запросы.
В запросах на модификацию данных используются те же параметры для поиска объектов по индексу,
что и в запросах на чтение: <index_name>
, <index_name>_ge
,
<index_name>_lt
и так далее.
Для изменения объекта выполните PUT-запрос с параметром <index_name>=<value>
,
однозначно идентифицирущим объект. Например, title=Berlin
:
В теле запроса должны содержаться новые значения изменяемых полей объектов в формате JSON.
curl --request PUT \
--url 'http://localhost:8081/data/City?title=Berlin' \
--data '{"population": 3520032}'
Параметр skip_result
(пустой ответ) также может применяться в запросах на
изменение данных:
curl --request PUT \
--url 'http://localhost:8081/data/City?title=Berlin&skip_result=true' \
--data '{"population": 3520032}'
Удаление данных¶
Для удаления данных определённого типа через REST API используются DELETE-запросы.
В запросах на модификацию данных используются те же параметры для поиска объектов по индексу,
что и в запросах на чтение: <index_name>
, <index_name>_ge
,
<index_name>_lt
и так далее.
Для удаления объекта выполните DELETE-запрос с параметром <index_name>=<value>
,
однозначно идентифицирущим объект. Например, title=Berlin
:
curl --request DELETE \
--url 'http://localhost:8081/data/City?title=Berlin'
Массовое удаление¶
Для массового удаления объектов можно использовать точечные DELETE-запросы с прохождением по списку объектов, например, полученному с помощью GET-запроса.
Однако, лучшим решением будет реализация массового удаления с помощью сервис-функций. Этот способ позволяет реализовать удаление с учётом особенностей схемы данных и в общем случае имеет лучшую производительность.