Я пытаюсь создать свое первое приложение Logic для фильтрации запросов от сторонней службы API.
Сторонний API отвечает как элементами SearchSummary
(Объект), так и Data
(Массив).
Я хочу вернуть в ответ только массив Data
, но постоянно получаю ошибку:
{
"error": {
"code": "NoResponse",
"message": "The server did not receive a response from an upstream server. Request tracking id '08584773567277623430271089584CU00'."
}
}
Если я изменю назначение переменной с @body('Parse_JSON')?['Data']
на @body('Parse_JSON')?['SearchSummary']
, то SearchSummary вернется нормально. Я пробовал добавить .items
к значению, но это тоже не помогает.
Когда я возвращаю length(@body('Parse_JSON')?['Data'])
в свой ответ, он возвращает точное число, так что там определенно есть элементы.
Может кто-нибудь объяснить, что я делаю неправильно?
Вот вид кода из моего приложения:
{
"definition": {
"$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
"actions": {
"Create_Contacts_Array": {
"inputs": {
"variables": [
{
"name": "OnlineContacts",
"type": "array",
"value": "@body('Parse_JSON')?['Data']"
}
]
},
"runAfter": {
"Parse_JSON": [
"SUCCEEDED"
]
},
"type": "InitializeVariable"
},
"HTTP": {
"inputs": {
"headers": {
"ApiToken": "XXX"
},
"method": "GET",
"uri": "https://api.companysearch.com/v1/data?query=X+Y+Z"
},
"runAfter": {},
"type": "Http"
},
"Parse_JSON": {
"inputs": {
"content": "@body('HTTP')",
"schema": {
"properties": {
"Data": {
"items": {
"properties": {
"MEMBERSHIP_DATA": {
"items": {
"properties": {
"companyId": {
"type": [
"string",
"null"
]
},
"companyName": {
"type": [
"string",
"null"
]
},
"dept": {
"type": [
"string",
"null"
]
},
"endDate": {
"type": [
"string",
"null"
]
},
"startDate": {
"type": [
"string",
"null"
]
},
"status": {
"type": [
"string",
"null"
]
},
"title": {
"type": [
"string",
"null"
]
}
},
"type": "object"
},
"type": "array"
},
"birthdate": {
"type": [
"string",
"null"
]
},
"dirId": {
"type": [
"string",
"null"
]
},
"firstName": {
"type": [
"string",
"null"
]
},
"lastName": {
"type": [
"string",
"null"
]
},
"middleName": {
"type": [
"string",
"null"
]
}
},
"type": "object"
},
"type": "array"
},
"SearchSummary": {
"properties": {
"DatabaseInfo": {
"properties": {
"IndexationDate": {},
"ReleaseNumber": {
"type": "string"
},
"UpdateDate": {
"type": "string"
},
"UpdateNumber": {
"type": "string"
},
"VersionNumber": {
"type": "string"
}
},
"type": "object"
},
"Offset": {
"type": "integer"
},
"RecordsReturned": {
"type": "integer"
},
"Sort": {},
"TotalRecordsFound": {
"type": "integer"
}
},
"type": "object"
}
},
"type": "object"
}
},
"runAfter": {
"HTTP": [
"SUCCEEDED"
]
},
"type": "ParseJson"
},
"Response": {
"inputs": {
"body": "@variables('OnlineContacts')",
"statusCode": "@outputs('HTTP')?['statusCode']"
},
"kind": "Http",
"runAfter": {
"Create_Contacts_Array": [
"SUCCEEDED"
]
},
"type": "Response"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"triggers": {
"When_a_HTTP_request_is_received": {
"kind": "Http",
"type": "Request"
}
}
},
"kind": "Stateless"
}
Вот пример полезных данных JSON, которые получает HTTP-запрос:
{
"SearchSummary": {
"TotalRecordsFound": 48,
"Offset": 0,
"RecordsReturned": 48,
"DatabaseInfo": {
"ReleaseNumber": "43",
"UpdateNumber": "431",
"UpdateDate": "2024-08-20T00:00:00",
"VersionNumber": "129.00",
"IndexationDate": null
},
"Sort": null
},
"Data": [
{
"birthdate": "1950-06-01T00:00:00",
"firstName": "Ian",
"middleName": "Charlie",
"lastName": "Jones",
"dirId": "P003577888",
"MEMBERSHIP_DATA": [
{
"companyId": null,
"companyName": null,
"startDate": null,
"status": null,
"endDate": null,
"title": null,
"dept": null
}
]
},
{
"birthdate": "1919-05-11T00:00:00",
"firstName": "Dorothy",
"middleName": "June",
"lastName": "Perkins",
"dirId": "P003890700",
"MEMBERSHIP_DATA": [
{
"companyId": null,
"companyName": null,
"startDate": null,
"status": null,
"endDate": null,
"title": null,
"dept": null
}
]
},
{
"birthdate": "1947-11-09T00:00:00",
"firstName": "Paul",
"middleName": "Dean",
"lastName": "Doe",
"dirId": "P003890600",
"MEMBERSHIP_DATA": [
{
"companyId": "GB04969800",
"companyName": "Acme Ltd 1",
"startDate": "2020-04-15T00:00:00",
"status": "Current",
"endDate": null,
"title": "Director",
"dept": "Board of Directors; Senior management"
},
{
"companyId": "GB07346800",
"companyName": "Acme Ltd 2",
"startDate": "2010-08-16T00:00:00",
"status": "Current",
"endDate": null,
"title": "Director",
"dept": "Board of Directors; Senior management"
},
{
"companyId": "GB06741800",
"companyName": "Acme Ltd 3",
"startDate": "2008-11-04T00:00:00",
"status": "Current",
"endDate": null,
"title": "Director",
"dept": "Board of Directors; Senior management"
}
]
}
]
}
@ 10p Я обновил свое исходное сообщение, оно появляется, когда в MEMBERSHIP_DATA более двух элементов, оно не работает. Когда я удаляю первый или последний элемент из MEMBERSHIP_DATA Яна Джонса, он работает нормально.
Благодарим вас за обновление вашего вопроса правильными данными, необходимыми для воспроизведения проблемы. Содержимое вашей переменной превысило 1024 байта - см. ссылку в моем ответе ниже.
Вам нужно использовать состояние с состоянием, и только тогда это будет работать.
Невозможно назначить массив из JSON новой переменной и вернуть ответ в приложении логики Azure.
У меня он отлично работает, используя дизайн ниже, даже с тремя данными о членстве:
В Compose сохранены данные образца с помощью 3 MEMBERSHIP_DATA. И моя схема Parse_Json:
{
"type": "object",
"properties": {
"SearchSummary": {
"type": "object",
"properties": {
"TotalRecordsFound": {
"type": "integer"
},
"Offset": {
"type": "integer"
},
"RecordsReturned": {
"type": "integer"
},
"DatabaseInfo": {
"type": "object",
"properties": {
"ReleaseNumber": {
"type": "string"
},
"UpdateNumber": {
"type": "string"
},
"UpdateDate": {
"type": "string"
},
"VersionNumber": {
"type": "string"
},
"IndexationDate": {}
}
},
"Sort": {}
}
},
"Data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"birthdate": {
"type": "string"
},
"firstName": {
"type": "string"
},
"middleName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"dirId": {
"type": "string"
},
"MEMBERSHIP_DATA": {
"type": "array",
"items": {
"type": "object",
"properties": {
"companyId": {},
"companyName": {},
"startDate": {},
"status": {},
"endDate": {},
"title": {},
"dept": {}
},
"required": [
"companyId",
"companyName",
"startDate",
"status",
"endDate",
"title",
"dept"
]
}
}
},
"required": [
"birthdate",
"firstName",
"middleName",
"lastName",
"dirId",
"MEMBERSHIP_DATA"
]
}
}
}
}
Убедитесь, что вы используете приведенную выше схему, поскольку она сработала для меня. Выход:
Ваш рабочий процесс завершается сбоем, поскольку он не сохраняет состояние, а не сохраняет состояние , а размер содержимого вашей переменной OnlineContacts превышает максимально допустимый размер в 1024 байта. Пожалуйста, обратитесь к https://docs.microsoft.com/en-us/azure/logic-apps/edit-app-settings-host-settings#variables, чтобы обновить максимальное настроенное значение.
Альтернативно вы можете попробовать использовать действие Compose
вместо переменной в рабочем процессе без сохранения состояния, если ваш сценарий это позволяет. Это создает единый вывод и позволяет избежать ограничений, связанных с содержимым переменных.
Можно ли сделать это синхронным вызовом, сохраняя при этом состояние?
@InvalidSyntax, конечно, возможно. Вы можете попробовать скопировать код рабочего процесса в новый рабочий процесс, только вместо "kind": "Stateless"
в конце JSON используйте "kind": "Stateful"
. Вы также можете попробовать использовать действие Compose
вместо переменной в рабочем процессе без сохранения состояния, если ваш сценарий это позволяет.
Кажется, теперь приложение работает, однако обработка занимает некоторое время (иногда в 2-3 раза больше времени выполнения). Есть ли для этого причина? и как я могу сделать это быстрее? Я осознаю, что даже не добавил всю остальную бизнес-логику, поэтому, скорее всего, она будет работать даже медленнее.
@InvalidSyntax, рабочие процессы без сохранения состояния обычно занимают меньше времени, поскольку они полностью выполняются в памяти и не используют внешнее хранилище. Это устраняет задержку, связанную с сохранением состояния. Если использование рабочих процессов без сохранения состояния необходимо для нужд вашего бизнеса, вы можете настроить параметр Runtime.Backend.VariableOperation.MaximumStatelessVariableSize
. Альтернативно вы можете протестировать, используя действие Compose
вместо переменной OnlineContacts.
Чем действие «Создать» отличается от использования переменной?
@InvalidSyntax, переменной можно присваивать разные значения несколько раз в ходе рабочего процесса. Однако, если вам нужно инициализировать переменную только один раз и вы не планируете изменять ее значение, вместо этого вы можете использовать действие Compose
. Это создает единый вывод и позволяет избежать ограничений, связанных с содержимым переменных.
Я протестировал ваш рабочий процесс, и он возвращает массив данных, как и ожидалось, без ошибок.