# RESTful API

CloudBase CMS 2.3.0 版本起,提供了通过 RESTful API 访问内容集合数据的能力。

# 开启 RESTful API

默认情况下,API 访问为关闭状态,此时无法使用 RESTful API 功能。你需要在项目设置中启用 API 访问功能,并设置访问路径后,才可以通过完整的访问路径访问 RESTful API

# 访问权限

默认情况下,RESTful API 无法访问任何数据,你需要设置允许访问/修改的内容:

  • 允许访问:能通过 RESTful API 读取内容

  • 允许修改:能通过 RESTful API 创建、更新内容

  • 允许删除:能通过 RESTful API 删除内容

# 请求路径

CloudBase CMS 的 RESTful API 请求路径由三部分组成:部署路径 + API 版本路径 + 服务路径。如

CMS 服务部署路径(下方的域名为示例,真实域名请查看您的 HTTP 访问服务默认域名 (opens new window)

https://xxxx.tcloudbase.com/api/

API 版本路径

/v1.0

服务路径,collectionName 为数据库集合名

/{collectionName}

则获取数据库名为 goods 的文档列表的请求路径为

GET https://xxx.tcloudbase.com/api/v1.0/goods

# 注意事项

  1. 查询数据时,默认最多一次返回 100 条数据

  2. 请求时传入的参数会覆盖默认的行为表现,如指定了返回结果要携带某个字段,但是在模型定义中此字段在 API 返回值中为隐藏的,遵循以上原则,则返回数据时,此字段会存在

  3. CMS 中默认会将上传的图片、文件存储在云存储中,并在数据库中存储 cloudId 形式的访问链接,使用 RESTful API 获取数据时,返回结果中的 cloudId 会被转换成 HTTP 链接。自动转换仅针对直接记录的 cloudId,关联文档中的 cloudId 不会处理。

  4. 使用 RESTful API 获取数据时,返回结果中的关联字段会被转换为完整的关联文档的值,如当一个商品内容模型中关联了标签内容模型(tag),数据库底层存储如下:

{
  "_createTime": 1603183501849,
  "_id": "112557505f8ea38e001e1fc210bd51ed",
  "_updateTime": 1604541130908,
  "name": "苹果",
  "price": 6299,
  "stock": 100000,
  "tags": [
    "b8df3bd65f681d43002b894d0bdce7ac"
  ]
}

则返回的结果为:

{
  "_createTime": 1603183501849,
  "_id": "112557505f8ea38e001e1fc210bd51ed",
  "_updateTime": 1604541130908,
  "name": "苹果",
  "price": 6299,
  "stock": 100000,
  "tags": [
    {
      "_id": "b8df3bd65f681d43002b894d0bdce7ac",
      "_createTime": 1603183501849,
      "_updateTime": 1604541130908,
      "name": "水果",
      "count": 10
    }
  ]
}

注意:关联转换只会处理返回数据中文档的关联,不会处理更深层的管理,即如果当关联的文档中也关联了其他文档时,则不会被转换。

# 公共参数

查询操作时,可以在 URL 中添加以下的 Query 参数

字段 类型 必填 说明
limit String 查询返回的文档数量,最大值 1000
skip String 查询偏移的文档数量
fields String JSON 对象字符串,例:{ key1: 1, key2: 0 },表示取 key1 字段,丢弃 key2 字段
sort String JSON 对象字符串,例:{ key1: 1, key2: -1 },表示按 key1 升序,key2 降序 排序

如:

GET /{collectionName}/?limit=10&skip=0&fields={"name":1}&sort={"name":1}

# 获取文档列表

根据简单的排序、分组条件,获取某内容集合的文档数据

# 请求路径

GET /{collectionName}/?limit={limit}&skip={skip}&fields={fields}&sort={sort}

# 响应体

字段 类型 说明
requestId String 请求 ID
data Object 返回结果
code String 发生错误时的错误码
message String 发生错误时的错误信息
total Number 文档总数量

响应示例

{
  "data": [
    {
      "_id": "ecdacfc05f3f28a800000bf51126de2f",
      "name": "test",
      "arr": ["sss", "sss", "ssss"],
      "markdown": "markdown 文本",
      "textarea": "ssssssssssssssssssssssssssssss",
      "_createTime": 1597974695982,
      "_updateTime": 1597974695982
    }
  ],
  "offset": 0,
  "limit": 10,
  "requestId": "1742eb3145c_11",
  "total": 1
}

# 查询文档列表

获取符合查询条件的文档列表

# 请求路径

POST /{collectionName}/find?limit={limit}&skip={skip}&fields={fields}&sort={sort}

# 请求体

如下所示,query 为查询条件, 并支持使用Query Command

{
  "query": {
    "price": { "$ge": 100 }
  }
}

# 响应

{
  "data": [
    {
      "_id": "ecdacfc05f3f28a800000bf51126de2f",
      "name": "test",
      "arr": ["sss", "sss", "ssss"],
      "markdown": "markdown 文本",
      "textarea": "ssssssssssssssssssssssssssssss",
      "_createTime": 1597974695982,
      "_updateTime": 1597974695982
    }
  ],
  "requestId": "1742eb3145c_11",
  "total": 1,
  "offset": 0,
  "limit": 10
}

# 获取单个文档

获取指定 Id 的文档

# 请求路径

GET /{collectionName}/{docId}

# 参数说明

参数 类型 是否必填 说明
docId String 内容文档 Id

# 响应

{
  "data": {
    "_id": "ecdacfc05f3f28a800000bf51126de2f",
    "name": "test",
    "arr": ["sss", "sss", "ssss"],
    "markdown": "markdown 文本",
    "textarea": "ssssssssssssssssssssssssssssss",
    "_createTime": 1597974695982,
    "_updateTime": 1597974695982
  },
  "requestId": "175d6218c00_6"
}

# 创建新的文档

创建新的内容文档

# 请求路径

POST /{collectionName}

# 请求体

请求体如下所示,data 为由新建文档组成的数组,支持一次创建多个文档

{
  "data": [
    {
      "name": "商品名称",
      "price": 100
    }
  ]
}

# 响应

{
  "id": "b5416b755f476d450088360c0054b6fb",
  "requestId": "1742f02d897_42"
}

# 更新单个文档

更新文档的内容,更新操作时,文档的最终结果为传入的 data 与现有文档内容的合并值,即同名字段替换原值。

# 请求路径

docId 为需要更新的文档

PATCH /{collectionName}/{docId}

# 请求体

请求体如下所示,data 为需要更新的内容,并且支持使用 Update Command

{
  "data": {
    "name": "商品名称",
    "price": 100
  }
}

# 响应

{
  "updated": 1,
  "requestId": "1742ef4477b_12"
}

# 批量更新文档

批量更新符合查询条件的数据为指定的内容

# 请求路径

PATCH /{collectionName}/

# 请求体

query 为查询条件,data 为更新的内容,如下面的示例,将 nameoldName 所有的内容, 更新namenewName,同时,query 也支持 Query Command

{
  "query": {
    "name": "oldName"
  },
  "data": {
    "name": "newName"
  }
}

# 响应

字段 类型 说明
updated Number 更新成功的文档数量
matched Number 符合条件的文档数量
upsert_id String 替换更新 插入新 doc 时存在,其余情况为 null
{
    "requestId": "2a3ec45e223a4",
    "updated": 1,
    "matched": 1,
    "upsert_id": null
}

# 替换单个文档

替换指定的文档为新的内容,替换操作只支持对单个文档进行。

# 请求路径

docId 为需要替换的文档

PUT /{collectionName}/{docId}

# 请求体

请求体如下所示,data 为需要更新的内容

{
  "data": {
    "name": "商品名称",
    "price": 100
  }
}

# 响应

{
    "updated": 1,
    "upsertedId": null,
    "requestId": "175d648919d_e"
}

# 删除单个文档

删除某个项目下某内容类型的指定文档

# 请求路径

docId 为需要删除的文档的 _id

DELETE /{collectionName}/{docId}

# 响应

{
  "deleted": 1,
  "requestId": "175d649a89f_a"
}

# 批量删除文档

批量删除符合查询条件的内容文档

# 请求路径

DELETE /{collectionName}/

# 请求体

如下所示,query 为查询条件, 并支持使用Query Command (opens new window)

{
  "query": {
    "price": { "$gt": 100 }
  }
}

# 响应

字段 类型 说明
deleted Number 删除成功的文档数
{
    "requestId": "23f416d4f8722",
    "deleted": 1
}

# Query Command

# $eq

表示字段等于某个值。

语法:{ <field>: { $eq: <value> }}

{
  "data": {
    "name": {
      "$eq": "cms"
    }
  }
}

# $ne

表示字段等于某个值。

语法:{ <field>: { $ne: <value> }}

{
  "data": {
    "name": {
      "$ne": "luke"
    }
  }
}

# $gt

表示字段大于某个值。

语法:{ <field>: { $gt: <value> }}

{
  "data": {
    "age": {
      "$gt": 18
    }
  }
}

# $gte

表示字段大于或等于某个值。

语法:{ <field>: { $gte: <value> }}

{
  "data": {
    "age": {
      "$gte": 18
    }
  }
}

# $lt

表示字段小于某个值。

语法:{ <field>: { $lt: <value> }}

{
  "data": {
    "age": {
      "$lt": 18
    }
  }
}

# $lte

表示字段小于或等于某个值。

语法:{ <field>: { $lte: <value> }}

{
  "data": {
    "age": {
      "$lte": 18
    }
  }
}

# $in

字段值在给定的数组中。

语法:{ <field>: { $in: [<value1>, <value2>, ... <valueN>] }}

{
  "data": {
    "category": {
      "$in": ["science", "computer"]
    }
  }
}

# $nin

字段值不在给定的数组中。

语法:{ <field>: { $nin: [<value1>, <value2>, ... <valueN>] }}

{
  "data": {
    "category": {
      "$nin": ["science", "computer"]
    }
  }
}

# $and

表示需同时满足指定的两个或以上的条件。

语法:{ $and: [{ <expression1> }, { <expression2> } , ... , { <expressionN> }] }

{
  "data": {
    "$and": [
      {
        "price": {
          "$lt": 200
        }
      },
      {
        "price": {
          "$gt": 100
        }
      }
    ]
  }
}

# $or

表示需满足所有指定条件中的至少一个。

语法:{ $or: [{ <expression1> }, { <expression2> }, ... , { <expressionN> }] }

{
  "data": {
    "$or": [
      {
        "price": {
          "$lt": 200
        }
      },
      {
        "price": {
          "$gt": 100
        }
      }
    ]
  }
}

# $nor

表示逻辑 "都不" 的关系,表示需不满足指定的所有条件。

语法:{ $nor: [{ <expression1> }, { <expression2> }, ... { <expressionN> }] }

{
  "data": {
    "$nor": [
      {
        "price": {
          "$lt": 200
        }
      },
      {
        "price": {
          "$gt": 100
        }
      }
    ]
  }
}

# Update Command

# $set

用于设定字段等于指定值,支持以点操作符表示法访问数组的元素和访问嵌入文档的字段

语法:{ $set: { <field>: <value>, ... } }

{
  "data": {
    "$set": {
      "text": "a",
      "style.color": "red",
    }
  }
}

# $inc

用于指示字段自增某个值,这是个原子操作

语法:{ $inc: { <field1>: <amount1≥, <field2>: <amount2>, ... }}

{
  "data": {
    "$inc": {
      "price": 1000
    }
  }
}


# $mul

用于指示字段自乘某个值

语法:{ $mul: { <field>: <number1> }}

{
  "data": {
    "$mul": {
      "price": 1.5
    }
  }
}


# $unset

用于表示删除某个字段

语法:{ $unset: { <field1>: "" }}

{
  "data": {
    "$unset": {
      "rating": ""
    }
  }
}

# $push

向数组尾部追加元素,支持传入单个元素或数组

语法:{ $push: { <field>: <value1> }}

{
  "data": {
    "$push": {
      "tags": {
        "$each": ["tag1", "tag2", "tag3"]
      }
    }
  }
}

# $pop

删除数组尾部元素

语法:{ $pop: { <field>: <-1 | 1> }}

1 表示从数组尾部剔除  元素,-1 表示从数组头部剔除元素

{
  "data": {
    "$pop": {
      "tags": 1
    }
  }
}

# 点操作符

云开发数据库支持点操作符表示法访问数组的元素、嵌套文档的字段

# 数组

"<array>.<index>"

如下面的数组,可以使用 contribs.2 获取 colors 数组的第三个元素 C

{
   colors: [ "A", "B", "C" ]
}

# 嵌套文档

"<embedded document>.<field>"

如下面的文档,可以使用 address.city 获取 city 的值,使用 contact.phone.number 获取 number 的值

{
   address: { city: "Sans" },
   contact: { phone: { type: "cell", number: "111-222-3333" } }
}