OpenAPI 接口文档
本文档描述如何调用平台提供的 OpenAPI 接口,包含认证方式、签名算法和接口示例。
NineData OpenAPI 介绍
OpenAPI(开放应用程序接口)是一套标准化的接口规范,允许开发者通过编程方式与外部系统或服务进行交互。它基于 RESTful 架构设计,通过 HTTP 协议提供标准化、轻量化、跨平台的数据通信能力,使不同系统间能够快速实现数据互通与功能集成。
NineData 的 OpenAPI 是面向数据管理领域的专业接口服务,为开发者提供一系列开放的应用程序接口,通过这些应用程序接口来管理 NineData 的数据源。
请求头参数
参数名称 | 必选 | 类型 | 说明 |
---|---|---|---|
access-key-id | 是 | string | 平台颁发的访问凭证 ID(AccessKey),在 NineData 控制台的「用户管理」中开启 AccessKey,即可查看 AccessKey 。 |
signature | 是 | string | 请求签名,用于验证请求合法性。如何获取,请参见本文的生成请求签名章节。 |
timestamp | 是 | string | UTC 时间戳,格式:<yyyy-MM-dd>T<HH:mm:ss>Z (示例:2024-05-31T09:15:33Z)。如何获取,请参见本文的时间戳规范章节。 |
Content-type | POST 时必选 | string | 固定为 application/json ,仅 POST 请求需要添加。 |
时间戳规范
时间戳用于请求头参数和生成请求签名,两者之间必须保持完全一致。
- 格式必须严格遵循:
<yyyy-MM-dd>T<HH:mm:ss>Z
- 使用 UTC 零时区(GMT+0)时间
- 服务端会校验时间戳与服务器时间的差异,超过 10 分钟的请求将被拒绝
可通过接口获取服务器时间:
curl http://<host>/openapi/now
生成请求签名
请求签名的生成需要按照如下方式拼接接口地址、SecretKey、当前时间戳,并通过 sha256sum
函数计算得出签名。
在 NineData 控制台的「用户管理」中,单击目标用户右侧操作列下的开启 AccessKey,并记录 SecretKey 。
根据如下方式拼接消息体。
<接口地址> + / + <SecretKey> + & + <当前时间戳>
示例:
/openapi/v1/region/list/Na12ssaaggffdd&2025-04-09T17:15:33Z
根据如下方式计算 SHA256 摘要,即可获得签名。
echo -n "<拼接的消息体>" | sha256sum | awk '{print $1}'
示例:
echo -n "/openapi/v1/region/list/Na12ssaaggffdd&2025-04-09T17:15:33Z" | sha256sum | awk '{print $1}'
快速接入流程
注意事项
- 时间戳必须与请求头中的 timestamp 完全一致。
- Windows 用户建议使用 Git Bash 执行签名计算。
操作流程
获取凭证:登录 NineData 控制台,在「用户管理」中开启 AccessKey,然后记录 AccessKey 和 SecretKey。
获取当前系统时间戳。
计算签名:在命令行执行
echo -n "/openapi/v1/region/list/<SecretKey>&<当前系统时间戳>" | sha256sum | awk '{print $1}'
。正式调用:拼接上述信息,发送接口调用请求。例如:
- GET 请求:
curl http://console.ninedata.cloud/openapi/v1/region/list -H "access-key-id:<AccessKey>" -H "timestamp:<当前系统时间戳>" -H "signature:<签名>"
- POST 请求:
curl -H "access-key-id:<AccessKey>" -H "timestamp:<当前系统时间戳>" -H "signature:<签名>" -H "Content-type:application/json" http://console.ninedata.cloud/openapi/v1/datasource/delete -d {"datasourceId":"<数据源 ID>"}
- GET 请求:
接口调用示例
本章节提供调用 NineData OpenAPI 的示例代码。
Bash 示例
#!/bin/bash
set -e
echo "current time : $(date)"
host=<IP>:<Port>
# 当前时间戳
timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
accessKeyId="<accessKeyId>"
accessKeySecret="<accessKeySecret>"
echo "timestamp= $timestamp"
echo "accessKeyId= $accessKeyId"
echo "accessKeySecret= $accessKeySecret"
get()
{
api=$1
param=$2
# 计算签名
signature=$(echo -n "$api/$accessKeySecret&$timestamp" \
| sha256sum | awk '{print $1}')
url="http://$host$api?$param"
if [ -z "$param" ]; then
url="http://$host$api"
fi
# GET请求
curl $url -H "access-key-id:$accessKeyId" -H "timestamp:$timestamp" -H "signature:$signature"
}
post()
{
api=$1
data=$2
# 计算签名
signature=$(echo -n "$api/$accessKeySecret&$timestamp" \
| sha256sum | awk '{print $1}')
# POST请求
curl -H "access-key-id:$accessKeyId" \
-H "timestamp:$timestamp" \
-H "signature:$signature" \
-H "Content-type:application/json" \
http://$host$api \
-d $data
}
get '/openapi/v1/region/list'
get '/openapi/v1/env/list' 'current=1&pageSize=10'
get '/openapi/v1/datasource/list' 'current=2&pageSize=10'
post '/openapi/v1/datasource/delete' '{"datasourceId":"<datasourceId>"}'
post '/openapi/v1/datasource/update' '{"datasourceId":"<datasourceId>","name":"数据源"}'
post '/openapi/v1/datasource/create' '{"name":"数据源","username":"root","host":"127.0.0.1","port":3306,"password":"123456","datasourceType":"MySQL","regionId":"cn-hangzhou","envId":"env-dev","networkType":"public"}'
Java 示例
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class ApiClient {
public static void main(String[] args) {
String host = "<IP>:<Port>";
String accessKeyId = "<accessKeyId>";
String accessKeySecret = "<accessKeySecret>";
// GET 示例
sendGet(host, "/openapi/v1/region/list", "", accessKeyId, accessKeySecret);
sendGet(host, "/openapi/v1/env/list", "current=1&pageSize=10", accessKeyId, accessKeySecret);
sendGet(host, "/openapi/v1/datasource/list", "current=2&pageSize=10", accessKeyId, accessKeySecret);
// POST 示例
sendPost(host, "/openapi/v1/datasource/delete",
"{\"datasourceId\":\"<datasourceId>\"}", accessKeyId, accessKeySecret);
sendPost(host, "/openapi/v1/datasource/update",
"{\"datasourceId\":\"<datasourceId>\",\"name\":\"数据源\"}", accessKeyId, accessKeySecret);
sendPost(host, "/openapi/v1/datasource/create",
"{\"name\":\"数据源\",\"username\":\"root\",\"host\":\"127.0.0.1\"," +
"\"port\":3306,\"password\":\"123456\",\"datasourceType\":\"MySQL\"," +
"\"regionId\":\"cn-hangzhou\",\"envId\":\"env-dev\",\"networkType\":\"public\"}",
accessKeyId, accessKeySecret);
}
// 生成 UTC 时间戳
private static String getTimestamp() {
return DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'")
.withZone(ZoneId.of("UTC"))
.format(Instant.now());
}
// 生成签名
private static String generateSignature(String api, String secret, String timestamp)
throws NoSuchAlgorithmException {
String data = api + "/" + secret + "&" + timestamp;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(data.getBytes(StandardCharsets.UTF_8));
StringBuilder hexString = new StringBuilder();
for (byte b : hash) {
String hex = String.format("%02x", b);
hexString.append(hex);
}
return hexString.toString();
}
// GET 请求
public static void sendGet(String host, String api, String params,
String accessKeyId, String accessKeySecret) {
try {
String timestamp = getTimestamp();
String signature = generateSignature(api, accessKeySecret, timestamp);
URL url = new URL("http://" + host + api + (params.isEmpty() ? "" : "?" + params));
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("access-key-id", accessKeyId);
conn.setRequestProperty("timestamp", timestamp);
conn.setRequestProperty("signature", signature);
printResponse("GET", conn);
} catch (Exception e) {
e.printStackTrace();
}
}
// POST 请求
public static void sendPost(String host, String api, String jsonBody,
String accessKeyId, String accessKeySecret) {
try {
String timestamp = getTimestamp();
String signature = generateSignature(api, accessKeySecret, timestamp);
URL url = new URL("http://" + host + api);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("access-key-id", accessKeyId);
conn.setRequestProperty("timestamp", timestamp);
conn.setRequestProperty("signature", signature);
conn.setRequestProperty("Content-Type", "application/json");
conn.setDoOutput(true);
try (OutputStream os = conn.getOutputStream()) {
byte[] input = jsonBody.getBytes(StandardCharsets.UTF_8);
os.write(input, 0, input.length);
}
printResponse("POST", conn);
} catch (Exception e) {
e.printStackTrace();
}
}
// 打印响应信息
private static void printResponse(String method, HttpURLConnection conn) throws IOException {
int status = conn.getResponseCode();
StringBuilder response = new StringBuilder();
try (BufferedReader br = new BufferedReader(
new InputStreamReader(status >= 400 ? conn.getErrorStream() : conn.getInputStream()))) {
String line;
while ((line = br.readLine()) != null) {
response.append(line);
}
}
System.out.printf("\n--- %s Response [%d] ---\n%s\n",
method, status, response.toString());
}
}
接口列表
公共接口
获取服务器时间:GET /openapi/now
数据源管理接口
接口名称 | 接口简介 |
---|---|
创建数据源 | 在 NineData 中创建一个新的数据库连接配置。 |
删除数据源 | 从 NineData 中删除目标数据源。 |
修改数据源 | 更新 NineData 中已录入数据源的连接信息。可修改数据源的名称、账号、密码、连接地址、端口、所属环境等信息。 |
获取数据源列表 | 分页查询数据源列表,支持通过数据源 ID、数据源名称、数据源类型进行过滤。 |
查询环境信息 | 获取 NineData 所有可用环境列表,支持通过环境名称过滤。 |
查询地域信息 | 获取 NineData 所有可用地域列表。 |