# 发布和调用 WorkItem API

将 WorkItem 的一个明确版本发布为可同步调用的 API Service，再使用服务名称和输入载荷调用它。发布、启用和调用是三个独立动作；WorkItem 存在不表示对应服务已经可用。

## 前提条件

- 已从 WorkItem Catalog 取得 `node_id`、版本、输入 Schema 和输出 Schema。
- 当前身份具有发布和调用 API Service 的权限。
- 自定义算子已经启用；使用指定计算实例时，当前身份也能使用该实例。

## 接口

| 方法与路径 | 用途 |
| --- | --- |
| `GET /workflow/v2/workitems/catalog/{node_id}/api-service?version={version}` | 读取已发布服务。 |
| `POST /workflow/v2/workitems/catalog/{node_id}/api-service` | 发布或更新服务。 |
| `POST /workflow/v2/workitems/catalog/{node_id}/api-service/enable?version={version}` | 启用服务。 |
| `POST /workflow/v2/workitems/catalog/{node_id}/api-service/disable?version={version}` | 停用服务。 |
| `POST /workflow/v2/workitems/catalog/{node_id}/api-service/invoke` | 调用已启用服务。 |

`node_id` 可能包含冒号。客户端构造路径时应进行一次标准 URL 编码，不要自行重复编码。

## 1. 发布服务

```bash
export NODE_ID='<workitem-node-id>'
export WORKITEM_VERSION='<workitem-version>'

curl -X POST \
  "$PRODUCT_API_BASE_URL/workflow/v2/workitems/catalog/$NODE_ID/api-service" \
  -H "X-API-Key: $PRODUCT_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d "{
    \"version\": \"$WORKITEM_VERSION\",
    \"timeout_seconds\": 60,
    \"max_concurrency\": 4,
    \"rate_limit_per_min\": 60
  }"
```

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| `version` | string | 是 | 要发布的 WorkItem 版本。调用和启停时必须使用同一版本。 |
| `compute_resource_id` | string | 否 | 指定计算实例。省略时使用平台当前的默认运行行为。 |
| `timeout_seconds` | integer | 否 | 单次调用超时。只使用当前接口接受的范围。 |
| `max_concurrency` | integer | 否 | 服务最大并发。应结合算子资源占用设置。 |
| `rate_limit_per_min` | integer | 否 | 每分钟调用限制。不能代替调用方自己的限速和重试控制。 |

成功响应的服务信息位于 `data.service`：

```json
{
  "code": "OK",
  "msg": "OK",
  "data": {
    "service": {
      "api_service_id": "<API_SERVICE_ID>",
      "node_id": "<NODE_ID>",
      "version": "<WORKITEM_VERSION>",
      "service_name": "<SERVICE_NAME>",
      "status": "<STATUS>",
      "result_mode": "<RESULT_MODE>",
      "method": "<METHOD>",
      "path": "<PATH>",
      "input_schema": "<INPUT_SCHEMA>",
      "output_schema": "<OUTPUT_SCHEMA>"
    }
  }
}
```

保存 `service_name`、`version`、服务状态和响应提供的调用信息。不要根据 WorkItem 名称自行拼接服务名称或路径。

## 2. 启用服务

如果发布响应显示服务未启用，调用启用接口：

```bash
curl -X POST \
  "$PRODUCT_API_BASE_URL/workflow/v2/workitems/catalog/$NODE_ID/api-service/enable?version=$WORKITEM_VERSION" \
  -H "X-API-Key: $PRODUCT_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{}'
```

再次读取服务，确认状态已经更新。服务停用后调用会失败；停用不会撤销此前调用产生的结果或外部副作用。

## 3. 调用服务

请求中的 `payload` 必须符合已发布服务的输入 Schema：

```bash
export SERVICE_NAME='<service-name-from-publish-response>'

curl -X POST \
  "$PRODUCT_API_BASE_URL/workflow/v2/workitems/catalog/$NODE_ID/api-service/invoke" \
  -H "X-API-Key: $PRODUCT_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d "{
    \"service_name\": \"$SERVICE_NAME\",
    \"type\": \"operator\",
    \"version\": \"$WORKITEM_VERSION\",
    \"payload\": {
      \"text\": \"hello\"
    }
  }"
```

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| `service_name` | string | 是 | 发布响应返回的服务名称。 |
| `type` | string | 是 | 服务类型。使用发布或调用信息提供的值；示例为 WorkItem Operator 的 `operator`。 |
| `version` | string | 是 | 已发布并启用的 WorkItem 版本。 |
| `payload` | object | 是 | 调用输入，应符合服务的输入 Schema。 |

调用结果位于 `data.result`。检查 `status`、`result` 和 `error`；存在 `case_id` 时同时保存，便于定位本次调用。HTTP 请求成功不替代对业务结果的校验。

## 常见问题

| 现象 | 先检查 | 下一步 |
| --- | --- | --- |
| 找不到服务 | `node_id`、版本和是否完成发布 | 读取同一 WorkItem 版本的 API Service，不自行构造服务名。 |
| 服务已停用 | `data.service.status` | 由有权限的用户启用后再调用，不自动反复重试。 |
| 输入无效 | 输入 Schema 和 `payload` | 按当前已发布版本修正字段和类型。 |
| 调用超时或失败 | `case_id`、状态、错误和计算实例 | 保留调用信息，确认服务端状态后再决定是否重试。 |

## 下一步

- [自定义算子与模板](custom-operators-templates.md)
- [创建和部署工作流](create-deploy-workflows.md)
