REST 故障排查
端点返回 404
现象: 请求 /api/EntityName 返回 404 Not Found。
原因:
- 实体未启用 REST(
rest.enabled为false)。 - URL 中的实体名与配置不匹配(大小写不一致)。
- REST 路径前缀被自定义。
排查步骤:
- 检查
dab-config.json中该实体的rest.enabled,确认不是false。省略时默认true。 - 确认 URL 中实体名与配置完全一致(区分大小写)。
/api/book和/api/Book是不同的路径。 - 如果使用
--rest.path自定义了 REST 前缀,确认 URL 使用了正确的路径。 - 检查
runtime.rest.enabled全局开关是否为true。
405 Method Not Allowed
现象: POST、PUT、PATCH 或 DELETE 返回 405 Method Not Allowed。
原因: 当前 HTTP 方法不在实体的 rest.methods 允许列表中(仅存储过程实体会限制方法)。
排查步骤:
- 检查
dab-config.json中该实体的rest.methods数组——是否包含了当前请求的方法。 - 存储过程默认只允许
POST,如需GET需显式配置"methods": ["GET"]。 - 表实体不支持通过
rest.methods限制 HTTP 方法——检查是否误将表实体当成了存储过程。
$filter 查询返回意外结果或报错
现象: $filter 返回空结果、错误结果或 Invalid filter expression 之类的错误。
常见原因与解决:
| 原因 | 解决 |
|---|---|
| 筛选语法不符合 OData 规范 | 字符串值必须用单引号:$filter=title eq 'Dune',不是双引号 |
| 字段名使用了数据库列名而非 API 名 | 如果配置了 fields.alias,筛选中使用别名 |
| 字段值类型不匹配 | 数字字段不加引号,字符串字段必须加引号 |
| URL 编码问题 | 空格应为 %20,单引号应为 %27 |
| 存储过程不支持筛选 | $filter 对存储过程实体无效 |
调试方法: 调高日志级别(--LogLevel Debug),查看生成的 SQL 语句,确认筛选条件是否被正确翻译为 WHERE 子句。
CORS 错误
现象: 浏览器调用 API 时因 CORS 策略被阻止。
排查步骤:
- 检查
dab-config.json中host.cors.origins数组是否包含了前端来源。 - 本地开发中可以设为
"origins": ["*"]快速解决。 - 生产环境应精确指定允许的域名,不使用
*。 - 修改 CORS 配置后重启服务。
POST 创建返回 400
常见原因:
| 原因 | 解决 |
|---|---|
request-body-strict 为 true,请求体有数据库不存在的字段 | 移除非表字段,或设为 "request-body-strict": false |
主键字段使用了自动生成列(IDENTITY、SERIAL)但请求体包含了该字段值 | 不在请求体中传自动生成的主键 |
| 视图无主键且请求了按主键路径的 PUT/PATCH | 在配置中指定 fields[].primary-key |
PUT 操作插入而非更新
原因: 默认情况下 PUT 是 upsert——记录存在则更新,不存在则插入。不带 If-Match 头时这是正常行为。
解决: 如果需要严格的"仅更新"语义,添加请求头 If-Match: *。记录不存在时会返回 404 而非创建。
无键 PUT/PATCH 失败
现象: 对自动生成主键的表执行 PUT /api/Book(URL 中无主键)失败。
原因: 所有主键列都是自动生成(IDENTITY 等)时,无键 PUT/PATCH 才被允许。如果存在非自动生成的主键列,URL 中必须包含这些主键。
排查: 确认表结构中的主键列是否都是自动生成类型。复合主键中只要有一列需要手动指定,就不能使用无键操作。
大数据量查询超时
排查步骤:
- 检查是否使用了分页——不传
$first时默认最多返回 100 条,但如果数据量大,查询本身可能超时。 - 检查数据库连接字符串中的超时参数(
Command Timeout/CommandTimeout/DefaultCommandTimeout),适当调高。 - 优化数据库查询——添加索引、优化 WHERE 条件。
下一步
- GraphQL 故障排查 — GraphQL 常见问题。
- 数据库连接故障排查 — 数据库连接问题。
