8. Запросы

Запросы к серверу выполняют методом POST и содержат в теле JSON-объект, состоящий из обязательных блоков:

  • Блок Credentials;

  • Блок Query;

Также пространстве методов server находятся методы, помогающие эксплуатации корректно конфигурировать хранилища данных относительно модели СМЭВ QL.

8.1. Блок Credentials

"credentials":{
    "system":{
        "mnemonic":"117bed7f-1c07-4079-a446-1161588db4e5",
        "instance_id":"ccb4a88f-f44b-43e7-8a97-3e45c8345e90",
        "user_id":"5ed38461-0907-486a-930a-7b443482932c"
    },
    "request":{
        "id":"df5a0073-c6be-4d8c-8eb2-9b2f4188a429",
        "sub_id":"0cdb59ce-224b-4118-8da1-c5ea08a5d955",
        "name":"driver_data",
        "purpose_id":"ed1170f1-3caa-4985-aa38-c9c5a190b770",
        "audit":"false",
        "audit_id":"fc1048fe-323d-4eeb-92df-5710b3d1d100",
        "audit_token":"39e47aac-45d2-44c1-8c26-2d9b28b1703b"
    },
    "signature":{
        "digest": null,
        "signature": null
    }
}

8.2. Блок Query

{
    "query": {
        "office": {
            "conditions": {
                "phone": "(347) 246-53-00"
            },
            "attributes": [
                "id",
                "phone",
                "name"
            ],
            "cabinet": {
                "conditions": {
                    "available": true
                },
                "attributes": [
                    "number",
                    "name",
                    "seats"
                ],
                "online_room": {
                    "conditions": {
                        "public": true,
                        "software": "zoom"
                    },
                    "attributes": [
                        "url"
                    ]
                },
                "parking": {
                    "conditions": {
                        "free": true,
                        "available": true
                    },
                    "attributes": [
                        "number",
                        "floor"
                    ]
                }
            }
        }
    }
}

8.2.1. Условия фильтрации Conditions

Объединение условий только по and (MVP)

Операции сравнения (op):

  • = (по умолчанию)

  • >

  • >=

  • <

  • <=

  • in

  • like (на перспективу)

Условия сравнения применимы к численным типам, датам, временам и таймштампам.

Варианты определения условий фильрации:

По равенству

{
    "query": {
        "office": {
            "conditions": {
                "phone": "(347) 246-53-00"
            }
        }
    }
}

На основе сравнения, краткая запись

{
    "query": {
        "office": {
            "conditions": {
                "area": [">","130"]
            }
        }
    }
}

На основе сравнения, полная запись

{
    "query": {
        "office": {
            "conditions": {
                "area": {
                    "op": ">",
                    "value": "130"
                }
            }
        }
    }
}

Комплексное условие

{
    "query": {
        "office": {
            "conditions": {
                "area": [">","130"],
                "floor": ["in", [1, 2]]
            }
        }
    }
}

OR (ИЛИ) в условиях

В conditions СМЭВ QL запроса поддерживается возможность указывать логический ИЛИ через зарезервированное слово or.

В блок or необходимо передать массив объектов, содержащих условия в свою очередь объединённые логическим И (AND).

Все условия, находящиеся на одном уровне с or группируются через логическое И (AND), как при обычном СМЭВ QL Запросе.

Пример:

"conditions": {
"lastname": "П",
"middlename": "И",
"birthdate": "2021-11-29 00:00:00",
"or": [
    {
        "vin": "в1"
    },
    {
        "vin2": "в2",
        "model": "bmw"
    }
],
"fetch": {
    "order": [["id", "ASC"], ["number", "DESC"]], // ASC default
    "page": [2, 10] // limit 10 offset 10
}
}

Условия описанного выше запроса (без учета fetch) соберутся в следующую конструкцию:

...
WHERE
        (lastname = 'П' AND middlename = 'И' AND birthdate = '2021-11-29 00:00:00')
    OR
        (vin ='в1')
    OR
        (vin2='в2' AND model = 'bmw')
...

8.2.2. Сортировка и пагинация

В блоке conditions опционально можно добавить блок fetch, в котором указывать условия сортировки и выбора страниц.

Пример блока:

"conditions": {
"lastname": "П",
"middlename": "И",
"birthdate": "2021-11-29 00:00:00",
"fetch": {
    "order": [["id", "ASC"], ["number", "DESC"]], // ASC default
    "page": [2, 10] // limit 10 offset 10
}
}

Если порядок сортировки не указан, то применяется ASC.

Если не указаны страницы, то по умолчанию всегда устанавливается первая страница с лимитом, равными параметру default блока pagination в файле конфигураций application.yaml.

Если запрашивается элементов на страницу больше, чем значение max, то должно использоваться дефолтное значение.

pagination:
    default: 100 //количество элементов на странице по умолчанию
    max: 1000 //максимальное количество элементов на странице

8.3. Эксплуатационные запросы

В пространстве методов server находятся методы, помогающие эксплуатации корректно конфигурировать хранилища данных относительно модели СМЭВ QL.

Метод возврата списка обязательных для создания индексов: GET server/indexes/required

В ответе должен возвращаться JSON с полями, используемыми в связях моделей (connections) и блоке conditions.allowed моделей, если они определены (conditions)

{
    "server": {
        "mnemonic": "#mnemonic",
        "instance": "#instance"
    },
    "indexes": {
        "connections": [{
                "source": "#source_name2",
                "table": "#table_name2",
                "fields": ["#field_name1", "#field_name2"]
            },
            {
                "source": "#source_name2",
                "table": "#table_name2",
                "fields": ["#field_name1", "#field_name2"]
            }
        ],
        "conditions": [{
                "source": "#source_name2",
                "table": "#table_name2",
                "fields": ["#field_name1", "#field_name2"]
            },
            {
                "source": "#source_name2",
                "table": "#table_name2",
                "fields": ["#field_name1", "#field_name2"]
            }
        ]
    }
}

8.4. Обработка запросов

8.4.1. Логирование мета-данных

У каждого запроса логируются данные из блока credentials в info и выше.

Формат строки лога:

{
    "level": "info",
    "time": "2000-01-01T01:01:01.111Z",
    "name": "#{smevql_server_name}.request",
    "system": {
        "mnemonic": "117bed7f-1c07-4079-a446-1161588db4e5",
        "instance_id": "ccb4a88f-f44b-43e7-8a97-3e45c8345e90",
        "user_id": "5ed38461-0907-486a-930a-7b443482932c"
    },
    "request": {
        "id": "df5a0073-c6be-4d8c-8eb2-9b2f4188a429",
        "sub_id": "0cdb59ce-224b-4118-8da1-c5ea08a5d955",
        "name": "driver_data",
        "purpose_id": "ed1170f1-3caa-4985-aa38-c9c5a190b770",
        "audit": "false",
        "audit_id": "fc1048fe-323d-4eeb-92df-5710b3d1d100",
        "audit_token": "39e47aac-45d2-44c1-8c26-2d9b28b1703b"
    }
}

Для каждого входящего запроса логируется каждый отправленный запрос к источнику:

{
    "level": "info",
    "time": "2000-01-01T01:01:01.111Z",
    "name": "#{smevql_server_name}.request",
    "system": {
        "mnemonic": "117bed7f-1c07-4079-a446-1161588db4e5",
        "instance_id": "ccb4a88f-f44b-43e7-8a97-3e45c8345e90",
        "user_id": "5ed38461-0907-486a-930a-7b443482932c"
    },
    "request": {
        "id": "df5a0073-c6be-4d8c-8eb2-9b2f4188a429",
        "sub_id": "0cdb59ce-224b-4118-8da1-c5ea08a5d955",
        "name": "driver_data",
        "purpose_id": "ed1170f1-3caa-4985-aa38-c9c5a190b770",
        "audit": "false",
        "audit_id": "fc1048fe-323d-4eeb-92df-5710b3d1d100",
        "audit_token": "39e47aac-45d2-44c1-8c26-2d9b28b1703b"
    },
    "source_request": {
        "id": "1cdb59ce-224b-4118-8da1-c5ea08a5d955",
        "source": "#{source_name}"
    }
}

Передача идентификаторов:

  1. source_request.id передается в queryId тела запроса в Простор.

  2. В x-request-id передается склейка {request.id};{request.sub_id};{source_request.id}

Логирование ответа

{
    "level": "info",
    "time": "2000-01-01T01:01:01.111Z",
    "name": "#{smevql_server_name}.response",
    "system": {
        "mnemonic": "117bed7f-1c07-4079-a446-1161588db4e5",
        "instance_id": "ccb4a88f-f44b-43e7-8a97-3e45c8345e90",
        "user_id": "5ed38461-0907-486a-930a-7b443482932c"
    },
    "request": {
        "id": "df5a0073-c6be-4d8c-8eb2-9b2f4188a429",
        "sub_id": "0cdb59ce-224b-4118-8da1-c5ea08a5d955",
        "name": "driver_data",
        "purpose_id": "ed1170f1-3caa-4985-aa38-c9c5a190b770",
        "audit": "false",
        "audit_id": "fc1048fe-323d-4eeb-92df-5710b3d1d100",
        "audit_token": "39e47aac-45d2-44c1-8c26-2d9b28b1703b"
    },
    "source_request": {
        "id": "1cdb59ce-224b-4118-8da1-c5ea08a5d955",
        "source": "#{source_name}"
    },
    "response": {
        "duration": "1ms",
        "code": 200,
        "result": "ok"
    }
}

8.4.2. Построение плана

Входные данные:

  • загруженные модели, описывающие атрибутный состав сущностей, связи между сущностями и источники;

  • запрос поступивший к серверу.

Необходимо определить набор запросов и порядок их исполнения СМЭВ QL сервером, обеспечить параллельное исполнение независимых запросов.

Вид плана запроса:

plan:
level: 1
    - source: prostore1
    query: SELECT id, phone, name FROM office WHERE phone = '(347) 246-53-00';
    pk: id
    alias: offices
level: 2
    - source: prostore2
    query: SELECT id, number, name, seats FROM cabinet WHERE office_id in (@offices) AND available = 'true';
    pk: id
    alias: cabinets
    - source: prostore1
    query: SELECT id, number, floor FROM parking WHERE office_id in (@offices) free = 'true' AND available = 'true';
    pk: number, flor
    alias: parkings
level: 3
    - source: vostok7
    query: SELECT url FROM online_room WHERE cabinet_id in (@cabinets) AND public = 'true' AND software = 'zoom';
    pk: null
    alias: online_rooms

Сначала параллельно выполняются запросы первого уровня, затем запрос второго уровня на основе данных полученных на первом уровне.

Фомирование плана запроса основывается на внешнем объединении данных в сторону основной сущности.

Порядок формирования плана запроса:

  • на основе query определяется основная запрашиваемая сущность;

  • на основе query определяются вспомогательные сущности;

  • на основе query определяются conditions к основной сущности;

  • на основе query определяются conditions к вспомогательным сущностям;

  • на первом уровне плана формируется запрос к основной сущности на основе:

    • запрошенных атрибутов;

    • данных модели;

    • условий фильтрации.

Отмечаются поля, составляющие PK.

Первичные ключи, даже отсутствующие в атрибутах запроса к серверу должны быть в запросе к источнику.

  • формируется запрос к вспомогательным сущностям на основе:

    • запрошенных атрибутов;

    • данных модели;

    • условий фильтрации;

    • с добавлением фильрации по PK основной или предшествующей сущности.

Первичные ключи, даже отсутствующие в атрибутах запроса к серверу должны быть в запросе к источнику, за исключением терминальных запросов.

План запроса

План запроса соответсвует иерархии построенной от основной сущности на основе связей (modelconnections).

Граф план