.. _smev_ql_request: Запросы ^^^^^^^^ Запросы к серверу выполняют методом POST и содержат в теле JSON-объект, состоящий из обязательных блоков: - Блок Credentials; - Блок Query; Также пространстве методов server находятся методы, помогающие эксплуатации корректно конфигурировать хранилища данных относительно модели СМЭВ QL. Блок Credentials ################ .. code-block:: json "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 } } Блок Query ########## .. code-block:: json { "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" ] } } } } } Условия фильтрации Conditions """""""""""""""""""""""""""""" Объединение условий только по `and` (MVP) Операции сравнения (op): - = (по умолчанию) - > - >= - < - <= - in - like (на перспективу) Условия сравнения применимы к численным типам, датам, временам и таймштампам. Варианты определения условий фильрации: По равенству .. code-block:: json { "query": { "office": { "conditions": { "phone": "(347) 246-53-00" } } } } На основе сравнения, краткая запись .. code-block:: json { "query": { "office": { "conditions": { "area": [">","130"] } } } } На основе сравнения, полная запись .. code-block:: json { "query": { "office": { "conditions": { "area": { "op": ">", "value": "130" } } } } } Комплексное условие .. code-block:: json { "query": { "office": { "conditions": { "area": [">","130"], "floor": ["in", [1, 2]] } } } } **OR (ИЛИ) в условиях** В **conditions** СМЭВ QL запроса поддерживается возможность указывать логический ИЛИ через зарезервированное слово **or**. В блок **or** необходимо передать массив объектов, содержащих условия в свою очередь объединённые логическим **И** (**AND**). Все условия, находящиеся на одном уровне с **or** группируются через логическое **И** (**AND**), как при обычном СМЭВ QL Запросе. Пример: .. code-block:: json "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) соберутся в следующую конструкцию: .. code-block:: yaml ... WHERE (lastname = 'П' AND middlename = 'И' AND birthdate = '2021-11-29 00:00:00') OR (vin ='в1') OR (vin2='в2' AND model = 'bmw') ... Сортировка и пагинация """"""""""""""""""""""" В блоке **conditions** опционально можно добавить блок **fetch**, в котором указывать условия сортировки и выбора страниц. Пример блока: .. code-block:: json "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, то должно использоваться дефолтное значение. .. code-block:: yaml pagination: default: 100 //количество элементов на странице по умолчанию max: 1000 //максимальное количество элементов на странице Эксплуатационные запросы ######################### В пространстве методов server находятся методы, помогающие эксплуатации корректно конфигурировать хранилища данных относительно модели СМЭВ QL. Метод возврата списка обязательных для создания индексов: ``GET server/indexes/required`` В ответе должен возвращаться JSON с полями, используемыми в связях моделей (connections) и блоке conditions.allowed моделей, если они определены (conditions) .. code-block:: json { "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"] } ] } } Обработка запросов ##################### Логирование мета-данных """"""""""""""""""""""""" У каждого запроса логируются данные из блока ``credentials`` в ``info`` и выше. Формат строки лога: .. code-block:: json { "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" } } Для каждого входящего запроса логируется каждый отправленный запрос к источнику: .. code-block:: json { "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}`` Логирование ответа .. code-block:: json { "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" } } Построение плана """"""""""""""""" Входные данные: - загруженные модели, описывающие атрибутный состав сущностей, связи между сущностями и источники; - запрос поступивший к серверу. Необходимо определить набор запросов и порядок их исполнения СМЭВ QL сервером, обеспечить параллельное исполнение независимых запросов. Вид плана запроса: .. code-block:: yaml 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 основной или предшествующей сущности. Первичные ключи, даже отсутствующие в атрибутах запроса к серверу должны быть в запросе к источнику, за исключением терминальных запросов. .. _request_plan: .. figure:: img/request_plan.png :align: center :alt: План запроса План запроса соответсвует иерархии построенной от основной сущности на основе связей (model\connections). .. _graf_plan: .. figure:: img/graf_plan.png :align: center :alt: Граф план