通用说明
API调用遵循HTTP协议,各Region采用不同的域名,具体域名为drds.{region}.baidubce.com。 数据交换格式为JSON,所有request/response body内容均采用UTF-8编码。
实名认证
使用云数据库 GaiaDB-X API的用户需要实名认证,没有通过实名认证的可以前往百度智能云官网控制台中的安全认证下的实名认证中进行认证。 百度云提供个人认证、企业认证两种认证方式,您可以根据实际情况选择一种进行认证。
API认证机制
所有API的安全认证一律采用Access Key与请求签名机制。 Access Key由Access Key ID和Secret Access Key组成,均为字符串。 对于每个HTTP请求,使用下面所描述的算法生成一个认证字符串。提交认证字符串放在Authorization头域里。服务端根据生成算法验证认证字符串的正确性。 认证字符串的格式为 bce-auth-v{version}/{accessKeyId}/{timestamp}/{expirationPeriodInSeconds}/{signedHeaders}/{signature}
。
- version是正整数。
- timestamp是生成签名时的UTC时间。
- expirationPeriodInSeconds表示签名有效期限。
- signedHeaders是签名算法中涉及到的头域列表。头域名之间用分号(; )分隔,如host; x-bce-date。列表按照字典序排列。(本API签名仅使用host和x-bce-date两个header)
- signature是256位签名的十六进制表示,由64个小写字母组成。
当百度云接收到用户的请求后,系统将使用相同的SK和同样的认证机制生成认证字符串,并与用户请求中包含的认证字符串进行比对。如果认证字符串相同,系统认为用户拥有指定的操作权限,并执行相关操作;如果认证字符串不同,系统将忽略该操作并返回错误码。
鉴权认证机制的详细内容请参见鉴权认证机制。
通信协议
支持HTTP和HTTPS两种调用方式。为了提升数据的安全性,建议通过HTTPS调用。
请求结构说明
数据交换格式为JSON,所有request/response body内容均采用UTF-8编码。
请求参数包括如下4种:
参数类型 | 说明 |
---|---|
URI | 通常用于指明操作实体,如: POST /v{version}/instance/{instanceId} |
Query参数 | URL中携带的请求参数,通常用来指明要对实体进行的动作 |
HEADER | 通过HTTP头域传入,如:x-bce-date |
RequestBody | 通过JSON格式组织的请求数据体 |
响应结构说明
响应值分为两种形式:
响应内容 | 说明 |
---|---|
HTTP STATUS CODE | 如200, 400, 403, 404等 |
ResponseBody | JSON格式组织的响应数据体 |
API版本号
参数 | 类型 | 参数位置 | 描述 | 是否必须 |
---|---|---|---|---|
version | String | URI参数 | API版本号,当前值为v1 | 是 |
幂等性
当调用创建资源的接口时,如果遇到了请求超时或服务器内部错误,用户可能会尝试重发请求,导致资源的超量创建。这时用户可以通过clientToken参数避免创建出比预期要多的资源,即保证请求的幂等性。
幂等性基于clientToken,clientToken是一个长度不超过64位的ASCII字符串,通常放在query string里,如https://drds.bj.baidubce.com/v1/instance?clientToken=be31b98c-5e41-4838-9830-9be700de5a20
。
如果用户使用同一个clientToken值调用创建接口,则服务端会返回相同的请求结果。因此用户在遇到错误进行重试的时候,可以通过提供相同的clientToken值,来确保只创建一个资源;如果用户提供了一个已经使用过的clientToken,但其他请求参数(包括queryString和requestBody)不同甚至url Path不同,则会返回IdempotentParameterMismatch的错误代码。
clientToken的有效期为24小时,以服务端最后一次收到该clientToken为准。也就是说,如果客户端不断发送同一个clientToken,那么该clientToken将长期有效。
日期与时间规范
日期与时间的表示有多种方式。为统一起见,除非是约定俗成或者有相应规范的,凡需要日期时间表示的地方一律采用UTC时间,遵循ISO 8601,并做以下约束:
- 表示日期一律采用
YYYY-MM-DD
方式,例如2014-06-01
表示2014年6月1日。 - 表示时间一律采用
hh:mm:ss
方式,并在最后加一个大写字母Z表示UTC时间。例如23:00:10Z
表示UTC时间23点0分10秒。 - 凡涉及日期和时间合并表示时,在两者中间加大写字母T,例如
2014-06-01T23:00:10Z
表示UTC时间2014年6月1日23点0分10秒。
服务域名
区域 | 服务端点Endpoint | 协议 |
---|---|---|
北京 | drds.bj.baidubce.com | HTTP and HTTPS |
广州 | drds.gz.baidubce.com | HTTP and HTTPS |
苏州 | drds.su.baidubce.com | HTTP and HTTPS |
武汉 | 暂不支持,敬请期待 | —— |
新加坡 | 暂不支持,敬请期待 | —— |
公共请求头与公共响应头
公共请求头
头域 | 说明 | 是否必须 |
---|---|---|
Authorization | 包含Access Key与请求签名。具体请参考鉴权认证 | 是 |
Content-Type | application/json; charset=utf-8 | 是 |
x-bce-date | 该请求创建的时间,表示日期一律采用YYYY-MM-DD方式,例如2014-06-01表示2014年6月1日。如果用户使用了标准的Date域,该头域可以不填。当两者同时存在时,以x-bce-date为准 | 是 |
公共响应头
头域 | 说明 |
---|---|
Content-Type | application/json; charset=utf-8 |
x-bce-request-id | 对应请求的requestId |
错误码
错误码格式
当用户访问API出现错误时,会返回给用户相应的错误码和错误信息,便于定位问题,并做出适当的处理。请求发生错误时通过Response Body返回详细错误信息,遵循如下格式:
参数名 | 类型 | 说明 |
---|---|---|
code | String | 表示具体错误类型 |
message | String | 有关该错误的详细说明 |
requestId | String | 导致该错误的requestId |
例如:
{
"code":"IllegalRequestUrl",
"message":"The requested url belongs to domain which is not under acceleration",
"requestId":" 81d0b05f-5ad4-1f22-8068-d5c9de60a1d7"
}
公共错误码
错误码 | 错误消息 | HTTP状态码 | 描述 |
---|---|---|---|
AccessDenied | Access denied. | 403 Forbidden | 无权限访问对应的资源 |
InappropriateJSON | The JSON you provided was well-formed and valid, but not appropriate for this operation. | 400 Bad Request | 请求中的JSON格式正确,但语义上不符合要求。如缺少某个必需项,或者值类型不匹配等。出于兼容性考虑,对于所有无法识别的项应直接忽略,不应该返回这个错误 |
InternalError | We encountered an internal error. Please try again. | 500Internal Server Error | 所有未定义的其他错误。在有明确对应的其他类型的错误时(包括通用的和服务自定义的)不应该使用 |
InvalidAccessKeyId | The Access Key ID you provided does not exist in our records. | 403 Forbidden | Access Key ID不存在 |
InvalidHTTPAuthHeader | The HTTP authorization header is invalid. Consult the service documentation for details. | 400 Bad Request | Authorization头域格式错误 |
InvalidHTTPRequest | There was an error in the body of your HTTP request. | 400 Bad Request | HTTP body格式错误。例如不符合指定的Encoding等 |
InvalidURI | Could not parse the specified URI. | 400 Bad Request | URI形式不正确。例如一些服务定义的关键词不匹配等。对于ID不匹配等问题,应定义更加具体的错误码,例如NoSuchKey |
MalformedJSON | The JSON you provided was not well-formed. | 400 Bad Request | JSON格式不合法 |
InvalidVersion | The API version specified was invalid. | 404 Not Found | URI的版本号不合法 |
OptInRequired | A subscription for the service is required. | 403 Forbidden | 没有开通对应的服务 |
PreconditionFailed | The specified If-Match header doesn't match the ETag header. | 412 Precondition Failed | 详见ETag |
RequestExpired | Request has expired. Timestamp date is XXX. | 400 Bad Request | 请求超时。XXX要改成x-bce-date的值。如果请求中只有Date,则需要将Date转换为datetime |
IdempotentParameterMismatch | The request uses the same client token as a previous, but non-identical request. | 403 Forbidden | clientToken对应的API参数不一样 |
SignatureDoesNotMatch | The request signature we calculated does not match the signature you provided. Check your Secret Access Key and signing method. Consult the service documentation for details. | 400 Bad Request | Authorization头域中附带的签名和服务端验证不一致 |
云数据库 GaiaDB-X 错误码
错误码 | 错误消息 | HTTP状态码 | 描述 |
---|---|---|---|
InstanceNotExist | Instance not exist. | 403 | 指定的云数据库 GaiaDB-X 实例不存在 |
AccessDenied | Access denied. | 403 | 禁止操作 |
InvalidAction | Invalid Action. | 400 | 非法操作 |
InternalFailure | We encountered an internal error. Please try again.. | 400 | 内部错误 |
ValidationError | Validation Error. | 400 | 校验失败 |
AlreadyMaxLimit | Already Max Limit. | 400 | 达到最大限额 |
DbinstanceStateChange | Operation not allowed. | 404 | 云数据库 GaiaDB-X 实例状态错误 |
InternalServerError | Internal Server Error. | 503 | 内部服务器错误 |
密码加密传输规范定义
所有涉及密码的接口参数都需要加密,禁止明文传输。密码一律采用AES-128-ECB加密算法进行加密,用SK的前16位作为密钥,用PKCS5Padding算法进行长度补全。此外,加密后生成的二进制字节流需要转成十六进制,并以字符串的形式传到服务端。
加密过程可参考以下代码,以Python为例,进行说明:
# -*- coding: utf-8 -*-
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
"""
若引入包Cipher后提示不存在该包,则安装pycryptodome包
"""
def encrypt(secretkey, password):
"""Encrypt adminpass by AES-128-ECB/PKCS5Padding, the key is secretkey."""
pendding = 16 - len(password) % 16
password += chr(pendding) * (pendding)
return b2a_hex(AES.new(secretkey[:16], AES.MODE_ECB).encrypt(password))
def decrypt(secretkey, password):
"""Decrypt adminpass by AES-128-ECB/PKCS5Padding, the key is secretkey."""
decrypted = AES.new(secretkey[:16], AES.MODE_ECB).decrypt(a2b_hex(password))
pendding = ord(decrypted[len(decrypted) - 1])
return decrypted[:-pendding]
排版约定
排版格式 | 含义 |
---|---|
<> | 变量 |
[] | 可选项 |
{} | 必选项 |
\ | 互斥关系 |
等宽字体 Courier New | 屏幕输出 |