При использовании устойчивых функций Azure версии 3 объект запроса триггера HTTP уже будет предварительно заполнен полем ввода с заголовками, методом и URL-адресом. Также есть поле тела. Однако при переходе на v4 поле ввода пустое (кроме значений, которые я сам туда ввел) и поле body отсутствует. Из-за этого я не могу использовать данные, находящиеся в поле тела, или значения, которые были бы в заголовке.
Вот пример из v3
"input": {
"method": "POST",
"url": "http://localhost:7071/api/orchestrators/analyze",
"originalUrl": "http://localhost:7071/api/orchestrators/analyze",
"headers": {
"accept": "*/*",
"connection": "keep-alive",
"host": "localhost:7071",
...
А вот из v4:
"input": {
"query": {
},
"params": {
"opName": "analyze"
}
},
Я попытался посмотреть, есть ли какие-либо расхождения между старым триггером из версии 3 и новым, который я использую для версии 4. Помимо очевидного изменения в структуре, я не вижу, что может быть причиной разницы.
Вот старый триггер из v3:
const df = require("durable-functions")
module.exports = async function (context, req) {
const client = df.getClient(context)
const instanceId = await client.startNew("Orchestrator", undefined, req)
context.log(`Started orchestration with ID = '${instanceId}'.`)
return client.createCheckStatusResponse(context.bindingData.req, instanceId)
}
А также его function.json:
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"route": "orchestrators/{opName}",
"methods": [
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"name": "starter",
"type": "orchestrationClient",
"direction": "in"
}
]
}
триггер v4:
const { app } = require('@azure/functions');
const df = require('durable-functions');
app.http('HttpTrigger', {
authLevel: "anonymous",
methods: ['POST'],
route: 'orchestrators/{opName}',
extraInputs: [df.input.durableClient()],
handler: async (request, context) => {
const client = df.getClient(context);
const instanceId = await client.startNew("Orchestrator", {input: request});
context.log(`Started orchestration with ID = '${instanceId}'.`);
return client.createCheckStatusResponse(request, instanceId);
},
});
Да. Действительно, модель V4 имеет другую конфигурацию, чем модель V3. Вы увидите, что модель V4 больше не использует файл function.json, как V3. Поэтому вам необходимо явно передать данные запроса в качестве входных данных в вашу функцию.
Я использовал приведенный ниже код, чтобы передать тело запроса, метод, URL-адрес и метод в качестве входных данных функции и получить ожидаемый ответ.
const { app } = require('@azure/functions');
const df = require('durable-functions');
const activityName = 'durableHello1';
df.app.orchestration('durableHello1Orchestrator', function* (context) {
const input = context.df.getInput();
const outputs = [];
outputs.push(yield context.df.callActivity(activityName, input));
return outputs;
});
df.app.activity(activityName, {
handler: (input) => {
const { body, headers, url, method } = input;
return `Hello, you sent a ${method} request to ${url} with body ${JSON.stringify(body)} and headers ${JSON.stringify(headers)}`;
},
});
app.http('durableHello1HttpStart', {
route: 'orchestrators/{orchestratorName}',
extraInputs: [df.input.durableClient()],
handler: async (request, context) => {
const client = df.getClient(context);
const body = await request.json();
const headers = request.headers;
const url = request.url;
const method = request.method;
const headersObj = {};
for (const [key, value] of headers.entries()) {
headersObj[key] = value;
}
const data = {
body,
headers: headersObj,
url,
method
};
const instanceId = await client.startNew(request.params.orchestratorName, { input: data });
context.log(`Started orchestration with ID = '${instanceId}'.`);
return client.createCheckStatusResponse(request, instanceId);
},
});
Выход-