云数据库API
清林云 BaaS 云数据库 OneDB 作为底层承载所有环境的应用数据,拥有理论上无限的数据存储能力和极快的数据读写速度,保障整个清林云 BaaS 系统的数据稳定和安全。
本章节详细说明清林云 BaaS 系统的云数据库 OneDB API 格式,类似于应用 API 格式TypeAPI,有部分区别。
云数据库 OneDB API 主要用于集成原有业务和原有数据上云。
基本结构
API 的基本 HTTP 结构如下:
API 示例
以浏览器的 fetch 请求为例:
fetch("https://环境地域.baasapi.com/cdb", {
"headers": {
"content-type": "application/json",
"envid": "你的环境ID",
"keyid": "你的环境密匙ID",
"Authorization": "(必选)由环境密匙密码构建的访问token"
},
"method": "POST",
"body": JSON.stringify({
appId: "user", // 必填
tableId: "User", // 必填
action: "get", // 必填
ids: {},
columns: {},
getColumns: [],
engineIndex: '',
orderType: 'desc',
endIds: {},
rowsLimit: 100,
filter: {},
condition: {},
updateType: '',
skip: 0,
getTotalCount: false,
querys: [],
sorters: [],
nextToken: '',
})
})
.then(res=>res.json())
.then(data=>console.log(data))
.catch(e=>console.log(e))
在下文中我们详细解释每一个字段的作用和场景。
请求地址 url
https://[环境地域].baasapi.com/cdb
其中[环境地域]
为你使用环境的地域代码,例如:https://cn-east-1.baasapi.com/cdb
。
地域代码可在控制台概览页面的环境上方看到。
以下为所有地域代码:
- 中国东部:cn-east-1
- 中国北部:cn-north-1
- 中国南部:cn-south-1
- 中国西部:cn-west-1
- 中国香港:cn-hk-1
- 美国西部:us-west-1
- 美国东部:us-east-1
- 英国:uk-1
- 新加坡:sg-1
- 澳大利亚:au-1
- 印度:in-1
另外专有云和私有云地域代码根据客户定制。
请求方法 method
统一为POST
。
请求头 headers
{
"headers": {
"Content-Type": "application/json",
"envid": "你的环境ID",
"keyid": "你的环境密匙Id",
"Authorization": "Bearer 云数据库jwtToken"
}
}
请求内容类型统一为 application/json
。
携带你的环境 ID 和密匙 ID。
注意此处Authorization
,需要使用上面环境密匙的密码去签名一个 jwtToken,设置签名的对象为:{identity:"cdb"}
,即身份为 cdb。最好加上一个过期时间,以防 token 不慎泄露造成影响。
JavaScript 示例:
const token =
'Bearer ' +
jwt.sign(
{
identity: 'cdb',
},
'环境密匙密码',
{ expiresIn: '1h' },
);
另外,需要前往应用市场 AppHub,安装云数据库应用(应用 ID:cdb),然后进入该环境的密匙管理界面,设置该密匙-分应用权限-选择云数据库应用,开通该密匙的应用权限后才可以访问云数据库 API。
示例:"Authorization": "Bearer eyJhbGVCJ9.eyJMzEwMjF9.mXM2b6yg"
(此处为删减 token,实际 token 要更长一些)
之所以流程稍微复杂,是因为访问云数据库的 token 权限比较高,必须保障一定的安全性。
基础安全:云数据库 API 地址必须为 HTTPS
第一重安全:确保访问云数据库 API 的 token 不暴露在公网,不放到前端代码中
第二重安全:能够访问云数据库 API 的环境密匙需单独开通该应用的权限
第三重安全:确保访问云数据库 API 的 token 有过期时间
第四重安全:如不慎泄露,请尽快取消该密匙的云数据库应用权限或删除该密匙
第五重安全:如不慎泄露并造成数据恶意删除,请联系客服进行数据恢复,该方法需要一定人力和时间,所以尽量在源头做好安全管控
请求内容 body
{
"appId": "user", // 必填
"tableId": "User", // 必填
"action": "get", // 必填
"ids": {},
"columns": {},
"getColumns": [],
"engineIndex": "",
"orderType": "desc",
"endIds": {},
"rowsLimit": 100,
"filter": {},
"condition": {},
"updateType": "",
"skip": 0,
"getTotalCount": false,
"querys": [],
"sorters": [],
"nextToken": ""
}
appId
是需要操作数据库表的应用 ID;
tableId
是需要操作数据库表的 ID;
action
是需要操作数据库表的动作,有以下几种:
get
查询单个数据。
必填项:ids
即该条数据的所有 id,示例:
{
"ids": {
"userId": "test",
"postId": "one"
}
}
可选项:getColumns
查询该条数据的部分列,如果不填则默认返回该条数据的全部列,示例:
{
"getColumns": ["name", "title"]
}
如果没有该条数据,则会返回null
。
getMany
查询多条数据。
必填项:ids
即查询范围的起始 id。
示例:
{
"ids": {
"userId": "test",
"postId": "CDB:tableMaxId" // 特殊值,代表最大
}
}
必填项:endIds
即查询范围的终止 id。
示例:
{
"endIds": {
"userId": "test",
"postId": "CDB:tableMinId" // 特殊值,代表最小
}
}
可选项:orderType
查询的排序方向,asc
为正序,即从小到大,desc
为倒序从大到小,默认为倒序,示例:
{
"orderType": "asc"
}
可选项:rowsLimit
需要返回数据的数量,默认为 100,最大为 5000,示例:
{
"rowsLimit": 100
}
可选项:filter
可以在返回的数据中进行一次过滤,减少不符合条件数据的网络传输,示例:
{
"filter": {
"conditionList": [
{
"column": "name",
"symbol": "=",
"value": "清林云"
},
{
"column": "title",
"symbol": "=",
"value": "BaaS"
}
],
"conditionLogical": "and"
}
}
conditionList
是过滤条件列表,可以有一个或多个过滤条件。过滤条件有三个值:
column
是需要过滤的字段名;
symbol
是字段的值和给定的值之间的比较运算符号,符号有:= != > >= < <=
,意思是等于 不等于 大于 大于等于 小于 小于等于
;
value
是需要比较的给定的值;
conditionLogical
是多个过滤条件的组合逻辑:
and
是默认值,即代表过滤后的数据要满足所有过滤条件;
not
代表过滤后的数据不会符合过滤条件,conditionList
只能有一个过滤条件;
or
代表过滤后的数据只符合过滤条件其中之一即可;
可选项:getColumns
查询所有数据的部分列,如果不填则默认返回数据的全部列,示例:
{
"getColumns": ["name", "title"]
}
create
新增一条数据。
必填项:ids
即新增数据的所有 id。
示例:
{
"ids": {
"userId": "test",
"postId": "CDB:nanoId" // 特殊值,代表21位随机值,类似uuid
}
}
另外还有几个特殊值:
CDB:timeId
:即 13 位时间戳加 10 位随机值,适用于极其严格要求数据不重复的场景;
CDB:microsecondId
:当数据表的类型为 A 系列并且该字段类型为microsecondId
时使用,格式为时间戳+3 位唯一事务数字;
必填项:columns
即新增数据的所有列字段。
示例:
{
"columns": {
"string1": "qqq",
"int2": 2,
"boolean3": true,
"float4": 2.3
}
}
可选项:condition
可以在新建数据时提前进行一次判断,示例:
{
"condition": {
"type": "ignore"
}
}
类型有如下几种:
ignore
: 忽略判断,直接新建数据,如果原先有该 ID 的数据,则会覆盖;
exist
: 期待已存在该 ID 的数据,如果原先有该 ID 的数据,则会覆盖;
notExist
: 期待不存在该 ID 的数据,如果原先有该 ID 的数据,则会报错;
默认是ignore
。
update
更新一条数据。
必填项:ids
即更新数据的所有 id。
示例:
{
"ids": {
"userId": "test",
"postId": "postone"
}
}
必填项:columns
即需要更新数据的字段。
示例:
{
"columns": {
"string1": "qqq",
"int2": 2,
"boolean3": true,
"float4": 2.3
}
}
可选项:condition
可以在新建数据时提前进行一次判断,示例:
{
"condition": {
"type": "ignore",
"conditionList": [
{
"column": "name",
"symbol": "=",
"value": "清林云"
},
{
"column": "title",
"symbol": "=",
"value": "BaaS"
}
],
"conditionLogical": "and"
}
}
类型有如下几种:
ignore
: 忽略判断,直接更新数据,如果原先没有该 ID 的数据,则会新建;
exist
: 期待已存在该 ID 的数据,如果原先没有该 ID 的数据,则会报错;
notExist
: 期待不存在该 ID 的数据,如果原先有该 ID 的数据,则会报错;
默认是ignore
。
更新数据的条件判断多了个列判断,和filter
一样,具体可见getMany
。
delete
删除一条数据。
必填项:ids
即删除数据的所有 id。
示例:
{
"ids": {
"userId": "test",
"postId": "posttwo"
}
}
可选项:condition
可以在删除数据时提前进行一次判断,示例:
{
"condition": {
"type": "ignore"
}
}
类型有如下几种:
ignore
: 忽略判断,直接删除数据,如果原先有该 ID 的数据,则会删除,没有也正常执行;
exist
: 期待已存在该 ID 的数据,如果原先没有该 ID 的数据,则会报错;
notExist
: 期待不存在该 ID 的数据,如果原先有该 ID 的数据,则会报错;
默认是ignore
。
search
可选项:querys
查询条件列表。查询条件由多个条件组合而成,满足条件的数据会返回,看如下示例:
{
"querys": [
{
"queryType": "equal", // 精确查询
"column": "title",
"value": "a" // 只有该列的值完全等于value时才可查到
},
{
"queryType": "equalMany", // 多词精确查询
"column": "title",
"value": ["b", "c"] // 列值满足一个即可
},
{
"queryType": "match", // 匹配查询,用于text类型字段
"column": "title", // 要查询的列名
"value": "this is 米饭" // 该分词可查到包含 this 米 米饭 的数据
},
{
"queryType": "matchPhrase", // 短语查询,用于text类型字段
"column": "title",
"value": "爱吃米饭" // 可以查到 我爱吃米饭,查不到 爱吃楼下的米饭
},
{
"queryType": "range", // 范围查询,用于int字段
"column": "title",
"rangeFrom": 100,
"rangeTo": 2000
},
{
"queryType": "prefix", // 前缀查询
"column": "title",
"value": "上海" // 可查到值为 上海市浦东新区 的数据
},
{
"queryType": "constScore", // 相关性查询
"column": "title",
"value": "查询值"
},
{
"queryType": "functionScore", // 因子相关性查询
"column": "title",
"factor": "因子",
"value": "查询值"
},
{
"queryType": "nested", // 嵌套查询,用于nested类型数据
"column": "title",
"searchKey": "customKey",
"searchValue": "someValue"
},
{
"queryType": "wildcard", // 通配符查询
"column": "title",
"value": "上海市??区*街道" // (*)代表任意字符序列,问号(?)代表任意单个字符
},
{
"queryType": "matchAll" // 所有行数查询或随机返回数据
},
{
"queryType": "distance", // 距离查询
"column": "location",
"centerPoint": "30.00,-90.22", // 中心点坐标,纬度在前,经度在后
"distance": 1200.5 // 和中心点的距离,单位:米
},
{
"queryType": "distanceBounding", // 地理矩形范围查询
"column": "location",
"topLeft": "30.20,-90.22", // 左上角坐标
"bottomRight": "30.00,-90.20" // 右下角坐标
},
{
"queryType": "distancePolygon", // 地理多边形查询
"column": "location",
"points": ["30.20,-90.22", "30.20,-90.22"] // 多边形端点坐标
},
{
"queryType": "exist", // 列存在查询
"column": "title" // 该列的值不为空即可返回
}
]
}
可选项:sorters
查询排序方式。先看示例:
{
"sorters": [
{
"sorterType": "ids",
"orderType": "asc"
},
{
"sorterType": "column",
"orderType": "desc",
"columnName": "title"
},
{
"sorterType": "union",
"orderType": "desc"
},
{
"sorterType": "distance",
"orderType": "desc",
"columnName": "location",
"points": ["0,0"]
}
]
}
排序方式可以有多个,会根据顺序依次排序。排序方式的字段解释如下:
sorterType
排序类型:- 值为
column
代表是以某个列排序,由columnName
决定; - 值为
ids
代表主键数据排序; - 值为
union
代表相关性排序,使用了 BM25 算法计算相关性; - 值为
distance
代表距离排序,计算列由columnName
决定,距离点由points
决定;
- 值为
columnName
排序列名orderType
值为asc
正序或desc
倒序,四种类型都需要该值,默认为倒序从大到小points
为排序距离点,格式为["0,0"]
如果设置只查询部分列,需要排序的列一定要包含在
getColumns
内。
可选项:rowsLimit
需要返回的数据量,默认为 20,最大为 100,示例:
{
"rowsLimit": 100
}
可选项:getTotalCount
是否返回符合查询条件的数据总数,默认为false
,示例:
{
"getTotalCount": true
}
可选项:skip
查询时从第几条数据开始,默认为 0,最大 5000,常用于查询多条数据时进行翻页的功能。
示例:
{
"skip": 0
}
可选项:nextToken
查询翻页的信息。
当查询数据时,如果符合条件的数据有 200 条,一次最多只能查询 100 条,那么返回的数据中就会携带前 100 条数据和nextToken
信息,前端收到后如果需要翻页,查询第 100-200 条数据,那么加入nextToken
即可查询到后面的数据。
skip
和nextToken
都可以进行查询翻页,但 skip 有最大值,超过最大值时的翻页就需要nextToken
来处理。
示例:
{
"nextToken": "xxx"
}
可选项:getColumns
查询所有数据的部分列,如果不填则默认返回数据的全部列,示例:
{
"getColumns": ["name", "title"]
}
返回内容
返回内容都是 JSON 格式,分别有成功和失败两种状态:
成功
成功会返回数据:
// action: "get"
{
"ids": "idsValue",
"columns": "columnsValue"
}
// action: "getMany"
{
"data": [
{
"ids": "idsValue",
"columns": "columnsValue"
}
],
"nextId": { "ids": "idsValue" }
}
// action: "create"
{
"ids": "idsValue"
}
// action: "update"
{
"ids": "idsValue"
}
// action: "update"
// updateType: "increment"
{
"columns": "columnsValue"
}
// action: "delete"
{
"success": true
}
// action: "search"
{
"data": [
{
"ids": "idsValue",
"columns": "columnsValue"
}
],
"nextToken": "xxx",
"totalCounts": 100
}
失败
失败返回遵循最新的通用 HTTP 异常返回标准草案,但是更改了状态码 400 为 200,加入了errCode
项进行判断,因为在某些请求客户端下,400 状态会导致一些程序异常。
{
"errCode": "错误码", // 通常为 1,第三方服务则是第三方错误码,验证请求是否出错一般判断是否有errCode即可,如 if(res.errCode){错误处理} else {正常处理}
"type": "错误的API",
"title": "错误原因",
"detail": "详细数据",
"instance": "请求ID和客户端数据"
}
其中,detail
是如下字段的 Json 字符串:
{
"envId": "环境ID",
"keyId": "环境Key",
"appId": "应用ID",
"tableId": "表ID",
"action": "执行动作"
}
instance
是如下字段的 Json 字符串:
{
"requestId": "请求ID", // 如果出现莫名错误,向客服提交该项用于追踪bug
"clientIP": "请求端IP地址", // 请求端IP地址
"referer": "请求来源", // 请求来源
"userAgent": "请求客户端", // 请求客户端
"date": "时间戳" // 时间戳
}