REST API:形状、分页与错误

第 1 课 · 共 6 课 约 8 分钟

区分 v2 原生响应与兼容 v1 信封,用 pageToken 翻页,按错误版本判断下一步。

本课目标

读完这一课,你将能够

  • 说出本体(Ontology)的 v2 与兼容 v1 接口路径,并区分两种响应
  • 用 pageToken 翻完一个列表,并知道页大小只是一个建议
  • 读懂错误,决定是改请求、等一等还是停下来

一份契约,四扇门

第 1 门课的「工具链层」画过四个入口的全貌,这门课逐个走进去:REST API、语义 SDK、aidc 命令行,还有留给智能体的那一扇。它们跑的是服务端的同一套代码:同样的权限判断,同样的校验,同样的 Action。SDK 和 CLI 都是 REST API 外面的一层,所以先把这一层看清楚,后面几课看到的就都是熟悉的东西。

REST

REST 接口

任何语言都能调,一个 HTTP 请求。凭证是开发者 Key(aidc-dk-);在 /semantic 里登录后,网页会话也行。

SDK

语义 SDK

在 Nexus 应用里用,自动带上访客的应用票据(aidc-at-),返回值已经剥掉了信封。

CLI

aidc 命令行

给开发者和脚本:输出 JSON,退出码稳定,凭证来自 aidc login。

AGENT

智能体的入口

智能体用 Agent Key(aidc-sk-);每个公司应用还有自己的 MCP 服务器。第 4 课细讲。

路径与信封

标准 Ontology 接口在 /api/v2/ontologies/… 下。/api/v1/ontologies/{ns}/… 仍兼容,{ns} 是组织的命名空间。下面用 v1 示例说明搜索、分页和信封。分支与提案也走 v1 接口。

路径的写法有一个例外要记住:这一组接口的路径段一律是 camelCase(objectTypes、loadObjects、applyBatch),AIDC 其他接口是 kebab-case(例如 password-tokens、device-codes)。这是有意为之的偏离,只适用于 Ontology 这一组。

下面在示例工厂(命名空间记作 cell-factory)里搜索 L01 产线上正在运行的工单,按到期时间升序,每页 20 条。条件写成一棵树,用 and、or、not 组合,最多嵌套三层。

curl https://www.ai-dc.ai/api/v1/ontologies/cell-factory/objects/workOrder/search \
  -H "Authorization: Bearer $AIDC_API_KEY" -H "Content-Type: application/json" \
  -d '{
    "where": { "type": "and", "value": [
      { "type": "eq", "field": "status", "value": "running" },
      { "type": "eq", "field": "lineCode", "value": "L01" }
    ] },
    "orderBy": { "fields": [{ "field": "dueAt", "direction": "asc" }] },
    "pageSize": 20
  }'

下面的 v1 示例使用 AIDC 信封 { ok, data, meta }。成功时响应体放在 data 里,所以对象数组在 data.data,令牌在 data.nextPageToken。失败时返回 error。v2 不加 AIDC 信封,成功时直接返回原生响应体;失败时用 Conjure 信封 { errorCode, errorName, errorInstanceId, parameters }。

{
  "ok": true,
  "data": {
    "data": [
      { "__primaryKey": "WO-1001", "__apiName": "workOrder", "__title": "WO-1001",
        "status": "running", "lineCode": "L01", "plannedQty": 40, "goodQty": 18 }
    ],
    "nextPageToken": "…"
  },
  "meta": { "requestId": "…", "generatedAt": "…", "version": "v1" }
}

分页:拿到令牌,再要下一页

凡是返回一串结果的接口都分页。响应里有 nextPageToken,说明还有下一页;没有,就是最后一页。要下一页,把同一个请求再发一遍并带上令牌:GET 接口放在查询参数 pageToken,POST 接口放在请求体的 pageToken。

  1. 01发请求第一页不带令牌
  2. 02收一页把 data.data 里的对象收下
  3. 03看令牌有 nextPageToken 就继续,没有就读完了
  4. 04带令牌再发同一个请求加上 pageToken

pageSize 只是建议。一页可能比你要的少,也可能多,但只要还有下一页,至少会有一条。所以「这一页没满」不等于「读完了」,判断只看有没有 nextPageToken。在 AIDC 里 pageSize 取 1 到 1,000 的整数。令牌是给紧接着的下一次请求用的,不要存下来隔天再用。

翻页期间数据还在变,所以可能看到重复,也可能漏掉:默认取的是每次请求那一刻的最新结果,不是同一时刻的快照。要精确的总数,别去数页数,用 count 或聚合。

错误:先判断,再决定

v1 失败时,HTTP 状态码和 error.code 说明原因,details 提供具体信息,meta.requestId 用于查日志。v2 要读 errorCode、errorName、errorInstanceId 和 parameters。下面的错误码表按 v1 写法列出。

意味着什么下一步
400 · 请求不合法(invalid_payload、invalid_query)请求本身不合规矩,details 里写明哪里不对改请求,别原样重试
401 / 403 · 凭证或权限(unauthorized、forbidden)没带凭证、凭证失效,或这把凭证没有权限换凭证或找管理者,重试没有用
404 · 找不到对象类型或对象不存在,或这把凭证看不到它核对 API name 与主键
409 · 冲突(rev_mismatch、branch_required)对象刚被别人改过;或智能体想直接改 main重新读取再改;智能体改到分支上
429 · 太频繁(rate_limited)太频繁,details.retryAfterSeconds 告诉你要等多久等够时间,再发同一个请求
5xx · 服务端错误服务端或上游的问题指数退避后重试

规律很简单:4xx 说明请求有问题,原样重试只会得到同样的结果,只有 429 要等;5xx 和网络错误才值得退避重试。

要点

  • 四扇门跑的是同一套服务端代码:权限、校验和 Action 都一样。
  • 标准路径是 /api/v2/ontologies/…;/api/v1/ontologies/{ns}/… 仍兼容。
  • v1 使用 AIDC 信封;v2 成功响应不加信封,错误用 Conjure 信封。
  • 有 nextPageToken 就还有下一页,pageSize 只是建议。
  • 4xx 先改请求(429 要等),5xx 才退避重试。

练一练

把一次查询拆开看

用示例工厂的工单练习,纸上写就行,不需要真的发请求。

照示例再写一个搜索请求:找出状态为 paused 的工单,按 dueAt 升序,每页 2 条。

小测

选一个答案,马上看解析。

Q1一个搜索请求要 pageSize 为 20,响应里只有 7 条,但带着 nextPageToken。接下来怎么办?

Q2本节 v1 示例中,一次成功搜索的对象数组在哪里?

Q3脚本收到 429,details.retryAfterSeconds 是 30。最合适的处理是?

延伸阅读