使用 REST API
数据墙DBW 自动为每个实体生成标准 REST 端点。所有端点返回统一的 JSON 结构,支持 OData 风格的查询参数。
端点结构
https://{host}/api/{entity}例如 Book 实体的完整端点集合:
| 端点 | 方法 | 操作 |
|---|---|---|
/api/Book | GET | 查询列表 |
/api/Book/id/1 | GET | 按主键查询 |
/api/Book | POST | 创建记录 |
/api/Book/id/1 | PUT | 替换记录 |
/api/Book/id/1 | PATCH | 更新字段 |
/api/Book/id/1 | DELETE | 删除记录 |
NOTE
路径和查询参数都区分大小写。
复合主键
实体有复合主键时,按主键查询的 URL 模式为:
/api/{entity}/{pk1-name}/{pk1-value}/{pk2-name}/{pk2-value}例如 GET /api/Inventory/categoryid/3/pieceid/1。
自定义 REST 路径
实体可通过 rest.path 配置自定义路径,支持正斜杠分隔的层次化 URL:
{ "rest": { "path": "shopping-cart/item" } }生成端点:/api/shopping-cart/item。
查询列表
curl
curl http://localhost:5000/api/BookJavaScript
const res = await fetch("http://localhost:5000/api/Book");
const data = await res.json();
console.log(data.value);Python
import requests
res = requests.get("http://localhost:5000/api/Book")
data = res.json()
for item in data["value"]:
print(item)响应格式
{
"value": [
{ "id": 1, "title": "示例图书", "year": 2023, "pages": 300 }
],
"nextLink": "http://localhost:5000/api/Book?$after=..."
}value 是记录数组,nextLink 仅在还有更多分页时出现。
按主键查询
curl http://localhost:5000/api/Book/id/1{
"value": [
{ "id": 1, "title": "示例图书" }
]
}按主键查询返回 value 数组(包含一条记录)。如果主键不存在,返回 404:
{
"error": {
"code": "Not Found",
"message": "No item found with primary key id = 999",
"status": 404
}
}NOTE
视图没有物理主键,需要在 fields 中通过 primary-key: true 标记主键字段。未指定主键时,按主键查询会返回 400 错误。
查询参数
REST API 支持 OData 风格的查询参数,按以下顺序组合:
| 参数 | 用途 | 示例 |
|---|---|---|
$filter | 条件筛选 | ?$filter=year ge 2000 |
$orderby | 排序 | ?$orderby=year desc,title asc |
$select | 选择字段 | ?$select=id,title |
$first | 每页条数 | ?$first=20 |
$after | 翻页游标 | ?$after=WyJpZCI6MjBd |
筛选运算符
eq 等于 ?$filter=title eq 'Dune'
ne 不等于 ?$filter=year ne 2000
gt 大于 ?$filter=pages gt 300
ge 大于等于 ?$filter=year ge 2000
lt 小于 ?$filter=pages lt 100
le 小于等于 ?$filter=year le 2020逻辑组合:
and 且 ?$filter=year ge 2000 and pages gt 300
or 或 ?$filter=title eq 'Dune' or title eq 'Foundation'排序
# 按年份降序,再按标题升序
curl "http://localhost:5000/api/Book?\$orderby=year desc,title asc"字段选择
# 只返回 id 和 title
curl "http://localhost:5000/api/Book?\$select=id,title"如果请求的字段不存在或不可访问,返回 400。
分页
# 每页 5 条
curl "http://localhost:5000/api/Book?\$first=5"
# 翻到下一页
curl "http://localhost:5000/api/Book?\$first=5&\$after=eyJpZCI6NX0="$first=-1 返回配置中允许的最大页大小(默认 100000 条)。
创建记录
curl -X POST http://localhost:5000/api/Book \
-H "Content-Type: application/json" \
-d '{"title": "新书", "year": 2024, "pages": 280}'成功返回 201,响应体包含创建的记录,并在 Location 头中返回新资源的 URL:
{
"value": [
{ "id": 100, "title": "新书", "year": 2024, "pages": 280 }
]
}JavaScript
const res = await fetch("http://localhost:5000/api/Book", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "新书", year: 2024, pages: 280 }),
});
const data = await res.json();Python
res = requests.post("http://localhost:5000/api/Book",
json={"title": "新书", "year": 2024, "pages": 280})
data = res.json()request-body-strict 行为
默认情况下(runtime.rest.request-body-strict: true),请求体中不存在于数据库表的字段会返回 400 Bad Request。设为 false 时忽略多余字段。
更新记录
PATCH 只更新提供的字段,其余字段保持不变:
curl -X PATCH http://localhost:5000/api/Book/id/100 \
-H "Content-Type: application/json" \
-d '{"title": "更新后的书名"}'PUT 替换整条记录(未提供的字段可能被置空或设为默认值)。
仅更新模式(If-Match)
默认情况下,PUT 和 PATCH 执行 upsert 操作——记录存在则更新,不存在则插入。携带 If-Match: * 头可以切换为仅更新模式——记录不存在时返回 404:
curl -X PATCH http://localhost:5000/api/Book/id/100 \
-H "Content-Type: application/json" \
-H 'If-Match: *' \
-d '{"title": "更新后的书名"}'| If-Match 值 | 行为 |
|---|---|
If-Match: * | 仅更新——记录存在则更新,不存在返回 404 Not Found |
If-Match: <其他值> | 拒绝 → 400 Bad Request(错误信息:Etags not supported, use '*') |
| 缺失 | 默认 upsert 行为 |
IMPORTANT
数据墙DBW 不支持逐记录 ETag 或 rowversion 匹配。* 仅断言"记录必须存在"。If-Match 仅影响 PUT 和 PATCH,对 DELETE 操作无影响。
删除记录
curl -X DELETE http://localhost:5000/api/Book/id/100成功返回 204(无响应体)。
错误处理
404 Not Found
{
"error": {
"code": "Not Found",
"message": "No item found with primary key id = 999",
"status": 404
}
}400 Bad Request
{
"error": {
"code": "Bad Request",
"message": "Invalid field 'xyz' in request body",
"status": 400
}
}404 Not Found(If-Match: * 记录不存在)
{
"error": {
"code": "Not Found",
"message": "No Update could be performed, record not found",
"status": 404
}
}403 Forbidden
{
"error": {
"code": "Authorization Failure",
"message": "The current role does not have permission to perform this action.",
"status": 403
}
}通用错误处理(JavaScript)
const res = await fetch("http://localhost:5000/api/Book");
const data = await res.json();
if (data.error) {
console.error(`${data.error.code}: ${data.error.message}`);
}Swagger 文档
开发模式下访问 /swagger 可以浏览所有 REST 端点、参数和响应格式,支持在线测试。
下一步
- 视图访问 — 将数据库视图暴露为 API。
- 使用 GraphQL API — GraphQL 调用方式。
