调用 elsa 工作流

工作流的执行有多种方式:

  • 使用触发器。
  • 使用 REST API
  • 使用 C# 代码。

使用触发器

当工作流配置为使用 触发器 启动时,该工作流将在触发器激活时开始执行。触发器如何激活取决于触发器类型。

例如,以HTTP 端点触发器开始的工作流可以通过调用触发器中配置的路径来启动。

HTTP端点配置

此工作流可以通过以下请求触发:

curl --location --request POST 'https://localhost:5001/workflows/test' \
--header 'Content-Type: application/json'

其他触发器示例包括:

  • 计时器触发器,在特定时间启动工作流。
  • 事件触发器,在接收到事件时启动工作流。
  • 消息触发器,在接收到消息时启动工作流。

使用 REST API

Elsa.Workflows.Api 包提供了两个用于执行工作流的端点:

  • /workflow-definitions/{workflow_definition_id}/execute:同步执行工作流定义。
  • /workflow-instances/{workflow_instance_id}/dispatch:异步执行工作流实例。

同步执行

在此上下文中,同步并不意味着工作流将在调用者的同一线程中执行。它仍然使用基于任务的异步编程。不同之处在于,调用者会等待工作流完成后再接收响应。

要同步执行工作流定义,可以使用以下请求:

curl --location --request POST 'https://localhost:5001/elsa/api/workflow-definitions/<workflow-definition-id>/execute' \
--header 'Content-Type: application/json' \
--header 'Authorization: ApiKey {api_key}'
--data-raw '{
    "input": {
        "InputData": {
            "dummyProp": "你好"
        }
    }
}'

授权

授权令牌的获取方式如 [ASP.NET 工作流服务器/安全性] 所述。

你可以在输入/输出选项卡为每个工作流定义输入和输出。 工作流输入和输出

响应应如下所示:

{
  "workflowState": {
    "definitionId": "2f6ba5802e254082b00bd4dab00e650a",
    "definitionVersion": 1,
    "status": "已完成",
    "subStatus": "已完成",
    "bookmarks": [],
    "completionCallbacks": [],
    "activityExecutionContexts": [],
    "output": {
      "OutputData": "你好!"
    },
    "properties": {
      "PersistentVariablesDictionary": {
        "f765d2c1ef7843ed862488ae6f191884:Workflow1:subvar": ""
      }
    },
    "id": "f765d2c1ef7843ed862488ae6f191884"
  }
}

id 字段包含工作流实例 IDoutput 字段包含工作流的输出。

关于输入和输出的更多信息,请参阅 输入/输出 章节。

异步执行

以下端点异步执行工作流:

/workflow-definitions/{workflow_definition_id}/dispatch`

请求与 /execute 端点大致相同,只是它不等待工作流完成。

相反,该端点会入队工作流以供执行并返回工作流实例 ID。

这是一个响应示例:

{
  "workflowInstanceId": "b235209459294b97904eaee89fe7f930"
}

使用 C# 代码

C# 代码执行工作流有两种方式:

  • 使用 IWorkflowRunner 服务。
  • 使用 IWorkflowRuntime 服务。

使用 IWorkflowRunner 服务

IWorkflowRunner 是一个低级服务,可以执行任何 IActivity 对象。

例如,以下代码执行名为 HelloWorld 的工作流:

var workflow = new Workflow
{
   Root = new WriteLine("Hello world!")
};

var workflowRunner = serviceProvider.GetRequiredService<IWorkflowRunner>();

await workflowRunner.RunWorkflowAsync(workflow);

工作流实例 ID

Workflow类本身也是一个活动!

使用 IWorkflowRunner 很简单,但它需要你自行了解要执行的工作流以及处理它创建的书签。此外,你还需自行管理工作流实例的持久化。

另一方面,IWorkflowRuntime 服务是一个高级服务,允许你根据提供的输入 触发 一个或多个工作流。工作流运行时与 IWorkflowDefinitionService 协同工作,从 IWorkflowDefinitionStore 中查找工作流。

这意味着,在使用 IWorkflowRuntime 服务触发工作流之前,你需要注册你的工作流。

当使用工作流设计器(或直接使用 REST API)创建工作流时,工作流会自动注册。如果你有自定义的 IWorkflowDefinitionProvider,其工作流也会自动注册。但如有必要,你也可以手动注册工作流。例如:

public class HelloWorldWorkflow : WorkflowBase
{
   protected override void Build(IWorkflowBuilder builder)
   {
        builder.Root = new WriteLine("Hello world!");
   }
}

services.AddElsa(elsa => elsa.AddWorkflow<MyWorkflow>());

下面的例子演示了如何使用 IWorkflowRuntime 服务调用现有工作流:

var workflowRuntime = serviceProvider.GetRequiredService<IWorkflowRuntime>();
var result = await workflowRuntime.StartWorkflowAsync("HelloWorldWorkflow");

工作流实例 ID

IWorkflowRuntime 服务常用于希望从事件处理器触发工作流的场景。例如,如果你实现了一个自定义触发器活动来监控目录中的文件变化,可以在文件创建时使用 IWorkflowRuntime 服务来触发工作流。另一个例子是当你想从消息队列触发工作流时,可以使用 IWorkflowRuntime 服务在收到消息时触发工作流。

在本文档中