Quickstart: Crie uma aplicação de Funções Duráveis em JavaScript

Utilize Durable Functions, uma funcionalidade do Funções do Azure, para escrever fluxos de trabalho sem servidor com estado em JavaScript. Neste quickstart, clonas e executas uma aplicação de exemplo que demonstra dois padrões comuns de orquestração:

  • Encadeamento de funções: Chama atividades sequencialmente (Tóquio → Seattle → Londres).
  • Fan-out/fan-in: Invoca atividades em paralelo em cinco cidades e, em seguida, agrega os resultados.

No final, terá ambas as orquestrações a correr localmente com o emulador Durable Task Scheduler e poderá ver o seu estado no painel.

  • Clonar e preparar o projeto de exemplo "Hello Cities".
  • Configura o emulador Durable Task Scheduler e o Azurite para desenvolvimento local.
  • Execute a aplicação de funções e acione ambas as orquestrações.
  • Reveja o estado da orquestração e os resultados no painel do Durable Task Scheduler.

Pré-requisitos

Configurar o emulador do Durable Task Scheduler

O emulador Durable Task Scheduler fornece um ambiente de desenvolvimento local para que possa testar orquestrações sem uma subscrição Azure. O anfitrião de Funções também requer Azurite para armazenamento local.

Inicie ambos os recipientes:

docker run -d --name dtsemulator -p 8080:8080 -p 8082:8082 \
  mcr.microsoft.com/dts/dts-emulator:latest

docker run -d --name azurite -p 10000:10000 -p 10001:10001 -p 10002:10002 \
  mcr.microsoft.com/azure-storage/azurite

Dica

Assim que o emulador estiver em execução, pode aceder ao painel do Durable Task Scheduler em http://localhost:8082 para monitorizar as orquestrações.

Executa a amostra de início rápido

  1. Navegue até ao diretório de exemplos Hello Cities:

    cd samples/durable-functions/javascript/HelloCities
    
  2. Dependências de instalação:

    npm install
    
  3. Verifique se o local.settings.json ficheiro contém a seguinte configuração:

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "node",
        "DURABLE_TASK_SCHEDULER_CONNECTION_STRING": "Endpoint=http://localhost:8080;TaskHub=default;Authentication=None"
      }
    }
    
  4. Inicie a aplicação de funções:

    func start
    
  5. Noutro terminal, desencadeie a orquestração de encadeamento de funções:

    $response = Invoke-RestMethod -Method POST -Uri http://localhost:7071/api/StartChaining
    $response
    

    A resposta contém URLs de estado da instância de orquestração. Copie o statusQueryGetUri valor e execute para verificar o resultado:

    Invoke-RestMethod -Uri $response.statusQueryGetUri
    
  6. Accione a orquestração fan-out/fan-in:

    $response = Invoke-RestMethod -Method POST -Uri http://localhost:7071/api/StartFanOutFanIn
    Invoke-RestMethod -Uri $response.statusQueryGetUri
    

Resultados esperados

O pedido POST devolve uma resposta JSON com URLs de estado. Por exemplo:

{
  "id": "<instanceId>",
  "statusQueryGetUri": "http://localhost:7071/runtime/webhooks/durabletask/instances/<instanceId>?code=...",
  "sendEventPostUri": "...",
  "terminatePostUri": "...",
  "purgeHistoryDeleteUri": "..."
}

Quando consulta statusQueryGetUri e o runtimeStatus da orquestração é Completed, pode encontrar os resultados da saudação no campo output. A orquestração de encadeamento regressa:

{
  "name": "chainingOrchestration",
  "runtimeStatus": "Completed",
  "output": ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
}

A orquestração de fan-out/fan-in regressa:

{
  "name": "fanOutFanInOrchestration",
  "runtimeStatus": "Completed",
  "output": ["Hello Tokyo!", "Hello Seattle!", "Hello London!", "Hello Paris!", "Hello Berlin!"]
}

Dica

Se runtimeStatus mostrar Running ou Pending, espere um momento e faça a pergunta statusQueryGetUri novamente.

Abra o painel do Durable Task Scheduler em http://localhost:8082 para ver o estado da orquestração e o histórico de execução.

Entenda o código

O exemplo utiliza o modelo de programação Node.js v4, onde todas as funções são definidas num único ficheiro (src/functions/helloCities.js).

Função de atividade

A sayHello atividade adota o nome da cidade e responde com uma saudação:

df.app.activity("sayHello", {
  handler: (city) => {
    return `Hello ${city}!`;
  },
});

Funções de orquestrador

O orquestrador de encadeamento chama sayHello sequencialmente para três cidades:

df.app.orchestration("chainingOrchestration", function* (context) {
  const outputs = [];
  outputs.push(yield context.df.callActivity("sayHello", "Tokyo"));
  outputs.push(yield context.df.callActivity("sayHello", "Seattle"));
  outputs.push(yield context.df.callActivity("sayHello", "London"));
  return outputs;
});

O orquestrador fan-out/fan-in programa as atividades em paralelo:

df.app.orchestration("fanOutFanInOrchestration", function* (context) {
  const cities = ["Tokyo", "Seattle", "London", "Paris", "Berlin"];

  // Fan-out: schedule all activities in parallel
  const tasks = cities.map((city) => context.df.callActivity("sayHello", city));

  // Fan-in: wait for all to complete
  const results = yield context.df.Task.all(tasks);
  return results;
});

Funções do cliente

As funções cliente ativadas por HTTP iniciam cada orquestração. Por exemplo, o iniciador de encadeamento:

app.http("StartChaining", {
  route: "StartChaining",
  methods: ["POST"],
  authLevel: "anonymous",
  extraInputs: [df.input.durableClient()],
  handler: async (request, context) => {
    const client = df.getClient(context);
    const instanceId = await client.startNew("chainingOrchestration");
    context.log(`Started chaining orchestration with ID = '${instanceId}'.`);
    return client.createCheckStatusResponse(request, instanceId);
  },
});

Configuração

O exemplo utiliza o emulador Durable Task Scheduler como backend de armazenamento. Isto está configurado em host.json:

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "DurableTask.Core": "Warning"
    }
  },
  "extensions": {
    "durableTask": {
      "hubName": "default",
      "storageProvider": {
        "type": "azureManaged",
        "connectionStringName": "DURABLE_TASK_SCHEDULER_CONNECTION_STRING"
      }
    }
  },
  "extensionBundle": {
    "id": "Microsoft.Azure.Functions.ExtensionBundle",
    "version": "[4.*, 5.0.0)"
  }
}

Limpeza de recursos

Pare os contentores do emulador quando terminar:

docker stop dtsemulator azurite && docker rm dtsemulator azurite

Passos seguintes