GraphQL-запросы в сервисе аудита
Сервис аудита поддерживает запросы GraphQL <https://graphql.org/>. Взаимодействие с GraphQL происходит через единую точку входа.
Для формирования GraphQL-запроса в строку с запросом добавляется /graphql
— https://[server]/services/auditservice/graphql/
, например, https://127.0.0.1:28651/graphql/
, .
GraphQL поддерживает Get-запросы: https://[server]/services/auditservice/graphql/?query={...}&variables={}
.
Для составления тестовых запросов можно воспользоваться https://eat.bananacakepop.com/.
Пример запроса GraphQL
Пример запроса всех пользователей, у которых менялся пароль
query {
get(where: {description: {contains: "Изменение пароля, пользователь:"}}) {
nodes {
login
result
source
eventDateTime
}
}
}
Методы GraphQL-запросов в сервисе аудита
Для получения записей в сервисе аудита используются следующие методы GraphQL:
- all;
- get.
Метод all
Метод all не поддерживает пагинацию и возвращает все записи аудита. Поддерживаются следующие входные параметры:
- сортировка по полю (order);
- имя журнала (journalName);
- фильтрация (where).
Пример составления части запроса
Пример запроса получения всех записей аудита с параметрами
- сортировка по убыванию;
- имя журнала — Security;
- описание содержит Вход;
- уровень важности — INFORMATIONAL.
query{
all(order:{eventDateTime:DESC}, journalName:"Security",
where:{description:{contains:"Вход"}and:{criticalLevel:{in:INFORMATIONAL}}}){
contentLocalizationKey
criticalLevel
description
eventData
eventDateTime
eventType
ip
journal
login
objectId
objectType
result
source
}
}
Метод get
Метод get поддерживает пагинацию и имеет следующие входные параметры:
- сортировка по полю (order);
- имя журнала (journalName);
- фильтрация (where).
Дополнительно поддерживаются следующие входные параметры:
- last;
- first;
- before;
- after.
Пример получения всех записей аудита с параметрами
- сортировка по убыванию;
- имя журнала — Security;
- описание содержит Создание;
- уровень важности — VERBOSE.
query{
get(order:{eventDateTime:DESC}, journalName:"Security",
where:{description:{contains:"Создание"}and:{criticalLevel:{in:VERBOSE}}})
{
edges{
node{
contentLocalizationKey
criticalLevel
description
eventData
eventDateTime
eventType
ip
journal
login
objectId
objectType
result
source
}
}
}
}
В node перечисляются поля, которые предполагается получить в ответе.
Ответ:
{
"data": {
"get": {
"edges": [
{
"node": {
"contentLocalizationKey": "",
"criticalLevel": "VERBOSE",
"description": "Создание субъекта.",
"eventData": "{name:\"BaseUserPermissions\";}",
"eventDateTime": "2021-06-22T15:47:33.000+03:00",
"eventType": "objectCreate",
"ip": "",
"journal": "Security",
"login": "",
"objectId": "",
"objectType": "subject",
"result": true,
"source": "security"
}
},
...//ещё 19 элементов
]
}
}
}
При отсутствии необходимости сортировки и фильтрации круглые скобки после get и all опускаются.
Примеры фильтрации и сортировки
Фильтрация и сортировка по возрастанию и убыванию с помошью метода get.
Следующий пример демонстрирует сортировку объектов по возрастанию:
get(order:{objectId:ASC})`
Следующие примеры демонстрируют выборку с помощью фильтрации:
- событий аудита по полю
result
не эквивалентногоtrue
get(where:{result:{neq:true}})
- событий аудита по полю
description
, не содержащегоtime
get(where:{description:{ncontains:"time"}})
Cортировкa по имени журнала
Для сервиса аудита реализована возможность сортировки по имени журнала с помощью параметра journalName. Запрос состоит из Graphql-запроса (query) и переменных.
Пример запроса
Запрос:
{
"query": "{\n get(order: {eventDateTime: DESC}, journalName: \"Security\",
where: {description: {contains: \"Вход\"},
and: {criticalLevel: {in: INFORMATIONAL}}})
{\n edges {\n node {\n contentLocalizationKey\n
criticalLevel\n description\n eventData\n
eventDateTime\n eventType\n ip\n
journal\n login\n objectId\n objectType\n
result\n source\n }\n }\n }\n}\n",
"variables": {}
}
Пагинация
Для сервиса аудита поддерживаются следующие виды пагинации:
- пагинация с помощью курсоров: с параметрами before, after. Принимают значение типа string. Каждый элемент имеет свой уникальный ключ.
- запрос на первые/последние n элементов: с параметрами first, last. Принимают значения типа int. По умолчанию, перечисление элементов идёт через все страницы.
Поддерживается комбинация видов пагинации.
Пример запроса без параметров
запрос:
query{
get{
totalCount
pageInfo{
hasNextPage
hasPreviousPage
endCursor
startCursor
}
edges{
node{
contentLocalizationKey
criticalLevel
description
eventData
eventDateTime
eventType
ip
journal
login
objectId
objectType
result
source
}
cursor
}
}
}
Ответ:
{
"data": {
"get": {
"totalCount": 60,
"pageInfo": {
"hasNextPage": true,
"hasPreviousPage": false,
"endCursor": "MTk=",
"startCursor": "MA=="
},
"edges": [
{
"node": {
"eventType": "create",
"ip": "",
"contentLocalizationKey": "",
"criticalLevel": "VERBOSE"
},
"cursor": "MA=="
},
...//ещё 18 элементов
]
}
}
}
Значение totalCount: 60 – общее число элементов.
Блок pageInfo :
- hasNextPage GraphQL: наличие следующей страницы;
- hasPreviousPage GraphQL: наличие предыдущей страницы;
- endCursor GraphQL: значение курсора последнего элемента на текущей странице;
- startCursor GraphQL: значение курсора первого элемента на текущей странице. Стандартный размер страницы – 20 элементов. Максимальное возможное количество элементов на странице: 2,147,483,647.
Для получения следующей страницы отправьте запрос с параметром after и укажите в параметре after значение курсора последнего элемента первой страницы.
Пример запроса с параметром after
Запрос
query{
get(after:"MTk="){
totalCount
pageInfo{
hasNextPage
hasPreviousPage
endCursor
startCursor
}
edges{
node{
eventType
ip
contentLocalizationKey
criticalLevel
}
cursor
}
}
}
Ответ В ответе со второй страницей элементов возвращаются элементы после значения курсора MTk=.
"data": {
"get": {
"totalCount": 60,
"pageInfo": {
"hasNextPage": true,
"hasPreviousPage": true,
"endCursor": "Mzk=",
"startCursor": "MjA="
},
"edges": [
//еще 20 элементов
]
}
}
В запросе возможна комбинация параметров.
Примеры комбинаций запроса с параметрами after и before с last/first
запрос:
get(after:"MTk=", first:2)
ответ:
дает первые два элемента на второй странице.
запрос:
get(after:"MTk=", last:2)
ответ:
последние два элемента в общем массиве независимо от страниц.
запрос:
get(before:"MTk=", last:2)
ответ:
последние два элемента до элемента с значением курсора MTk=.
Совместно параметры after и before не работают, но запрос не выдаст ошибку, а проигнорирует before
Пример получения предыдущей страницы по курсору из текущей страницы
пример получения объектов аудита:
get(journalName:"Security", before:"NjA=", last:20)
укажите в параметре before первый курсор текущей страницы, в параметре last – стандартный размер страницы (20 элементов).
Любые возвращаемые поля в запросе необязательны, но необходимо указать по крайней мере одно поле.
Запрос query для записей аудита
Запрос query для записей аудита поддерживает сортировку, фильтрацию и пагинацию; может содержать необязательный параметр journalName.
Значения criticalLevel для аудита:
- Critical
- Error
- Warning
- Informational
- Verbose
Получение записей аудита со следующими параметрами:
- сортировка по убыванию;
- имя журнала – Security;
- описание содержит Создание;
- уровень важности – VERBOSE;
- первые два элемента после элемента со значением курсора MTk=.
Пример query для аудита
query{
get(order:{eventDateTime:DESC}, journalName:"Security",
where:{description:{contains:"Создание"}and:{criticalLevel:{in:VERBOSE}}}, first:2, after:"MTk=")
{
totalCount
pageInfo{
endCursor
startCursor
hasNextPage
hasPreviousPage
}
edges{
node{
contentLocalizationKey
criticalLevel
description
eventData
eventDateTime
eventType
ip
journal
login
objectId
objectType
result
source
}
cursor
}
}
}
Запрос query полностью:
Полные запросы для сервера состоят из query + variables (в примере используется пустое значение переменных).
{
"query": "{\n get(order: {eventDateTime: DESC}, journalName: \"Security\",
where: {description: {contains: \"Создание\"}, and: {criticalLevel: {in: VERBOSE}}},
first: 2, after: \"MTk=\")
{\n totalCount\n
pageInfo {\n endCursor\n startCursor\n
hasNextPage\n hasPreviousPage\n }\n
edges {\n
node {\n contentLocalizationKey\n criticalLevel\n
description\n eventData\n eventDateTime\n
eventType\n ip\n journal\n login\n
objectId\n objectType\n
result\n source\n }\n
cursor\n }\n }\n}\n",
"variables": {}
}
Для составления тестовых запросов можно воспользоваться https://eat.bananacakepop.com/.
Graphql-запросы на C#
Для составления Graphql-запросов на C# можно использовать сторонние библиотеки, например GraphQL.Client или graphql-dotnet.
Пример запроса C#
GraphQLHttpClient graphQLClient = new
GraphQLHttpClient("https://api.example.com/graphql",
new NewtonsoftJsonSerializer());
GraphQLRequest request = new GraphQLRequest {
Query = @"
{
student{
name
}
}"
};
var graphQLResponse = await graphQLClient.SendQueryAsync<ResponseType>(request)