跳到主要内容

OpenAPI 接口文档

本文档描述如何调用平台提供的 OpenAPI 接口,包含认证方式、签名算法和接口示例。

NineData OpenAPI 介绍

OpenAPI(开放应用程序接口)是一套标准化的接口规范,允许开发者通过编程方式与外部系统或服务进行交互。它基于 RESTful 架构设计,通过 HTTP 协议提供标准化、轻量化、跨平台的数据通信能力,使不同系统间能够快速实现数据互通与功能集成。

NineData 的 OpenAPI 是面向数据管理领域的专业接口服务,为开发者提供一系列开放的应用程序接口,通过这些应用程序接口来管理 NineData 的数据源。

请求头参数

参数名称必选类型说明
access-key-idstring平台颁发的访问凭证 ID(AccessKey),在 NineData 控制台的「用户管理」中开启 AccessKey,即可查看 AccessKey
signaturestring请求签名,用于验证请求合法性。如何获取,请参见本文的生成请求签名章节。
timestampstringUTC 时间戳,格式:<yyyy-MM-dd>T<HH:mm:ss>Z(示例:2024-05-31T09:15:33Z)。如何获取,请参见本文的时间戳规范章节。
Content-typePOST 时必选string固定为 application/json,仅 POST 请求需要添加。

时间戳规范

时间戳用于请求头参数和生成请求签名,两者之间必须保持完全一致。

  • 格式必须严格遵循:<yyyy-MM-dd>T<HH:mm:ss>Z
  • 使用 UTC 零时区(GMT+0)时间
  • 服务端会校验时间戳与服务器时间的差异,超过 10 分钟的请求将被拒绝
  • 可通过接口获取服务器时间:

    curl http://<host>/openapi/now

生成请求签名

请求签名的生成需要按照如下方式拼接接口地址SecretKey当前时间戳,并通过 sha256sum 函数计算得出签名。

  1. NineData 控制台的「用户管理」中,单击目标用户右侧操作列下的开启 AccessKey,并记录 SecretKey

  2. 根据如下方式拼接消息体。

    <接口地址> + / + <SecretKey> + & + <当前时间戳>

    示例:/openapi/v1/region/list/Na12ssaaggffdd&2025-04-09T17:15:33Z

  3. 根据如下方式计算 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 执行签名计算。

操作流程

  1. 获取凭证:登录 NineData 控制台,在「用户管理」中开启 AccessKey,然后记录 AccessKeySecretKey

    accesskey1

    accesskey2

  2. 获取当前系统时间戳。

  3. 计算签名:在命令行执行 echo -n "/openapi/v1/region/list/<SecretKey>&<当前系统时间戳>" | sha256sum | awk '{print $1}'

  4. 正式调用:拼接上述信息,发送接口调用请求。例如:

    • 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>"}

接口调用示例

本章节提供调用 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 所有可用地域列表。

账号管理接口

接口名称接口简介
获取账号列表分页查询 NineData 账号列表,支持通过账号 ID、账号名称、账号登录名进行过滤。

角色管理接口

接口名称接口简介
获取角色信息分页查询 NineData 系统中已创建的角色列表,支持获取角色 ID、名称和类型。

权限接口

接口名称接口简介
查询账号的数据源权限查询指定账号拥有的数据源权限分组,包括环境列表、数据源信息和权限项信息。
查询角色的数据源权限查询指定角色拥有的数据源权限,包括环境、数据源及权限操作。
查询拥有目标数据源权限的角色指定一个数据源,查看拥有该数据源权限的所有角色。
查询拥有目标数据源权限的账号指定一个数据源,查看拥有该数据源权限的所有账号。
查询目标数据源的权限申请记录指定一个数据源,查看针对该数据源提交过的权限申请记录。

审计日志接口

接口名称接口简介
查询操作日志分页查询 NineData 操作审计日志,支持根据账号、时间范围、模块、事件类型等进行过滤。
查询 SQL 执行日志分页查询 NineData SQL 执行日志,支持根据账号、时间、数据源、库表、SQL 类型等条件过滤。

数据复制任务接口

接口名称接口简介
查询复制任务列表分页查询 NineData 复制任务,支持按状态、数据源、任务类型等条件筛选。
查询复制任务状态获取指定复制任务的状态信息,包括当前执行的子任务及进度。