数据管理DMS提供的数据服务,能够将您在DMS中管理的数据以API的形式快速对外输出。本文为您介绍对API进行开发、测试、发布、上线、下线等操作。
前提条件
已将数据源录入DMS,且已开启安全托管(稳定变更和自由操作实例)或安全协同功能。更多信息,请参见云数据库录入、他云/自建数据库录入、开启安全托管、变更管控模式。
注意事项
此功能正在邀测中,仅部分用户可以使用。
修改后的API,需要进行重新发布才会生效。
删除API时,会对API进行下线处理,即同步删除服务开发和服务管理页签中的API。
执行删除操作后,相关数据将无法恢复,请谨慎进行操作。
服务开发
在服务开发页签,您可新建、编辑、测试API。API后发布,您可以将开发态的API发布至线上通过HTTPS和SSE协议调用该API。
进入服务开发页签
登录数据管理DMS 5.0。
在顶部菜单栏中,选择。
说明若您使用的是极简模式的控制台,请单击控制台左上角的
图标,选择。可选:单击服务开发页签。
新建目录
单击目录右侧的
,并选择新建目录。在弹出的新建目录对话框,输入目录名称。
说明目录名称由汉字、英文字母、数字、下划线(_)组成,有如下要求:
名称唯一。
以英文字母或者汉字开头。
长度为4~50个字符。
可选:输入业务描述。
单击确认。
新建并配置API
可选:新建目录。
新建API。
在目标目录的右侧,单击
,并选择新建API。在弹出的新建API对话框,输入API名称。
说明API名称由汉字、英文字母、数字、下划线(_)组成,有如下要求:
名称唯一。
以英文字母或者汉字开头。
长度为4~50个字符。
可选:输入业务描述。
在路径文本框,输入API的调用路径。
说明该路径为API调用地址的组成部分,仅只支持英文、数字、下划线(_)、短划线(-),必须以
/开头(例如/item/add)且唯一。单击确认。
配置API。
单击目标API名称。
配置API参数。
配置项
配置条件
说明
类别
参数
API模式
选择模式
必配
支持向导模式和脚本模式。
向导模式:通过可视化的方式选择表、字段,定义API的数据查询配置。
脚本模式:通过手动编写SQL脚本和变量的方式,定义API的数据查询配置。
选择表
数据源类型
必配
待查询的数据库类型,当前仅支持MySQL和PolarDB MySQL版。
数据源名称
待查询的数据库。
说明可以通过输入关键字,快捷查询当前用户有查询权限的数据库。
数据表名称
向导模式
待查询的数据表。
说明可以通过输入关键字,快捷查询目标表。
选择参数
返回结果分页
向导模式
是否对返回结果分页。
设置为请求参数
是否将字段设置为请求参数。
若您勾选字段前的设置为请求参数,该字段将会被添加到右侧的请求参数中。
说明将字段设置为请求参数后,您可以在右侧单击请求参数,设置字段信息。
设置为返回参数
是否将字段设置为返回参数。
若您勾选字段前的设置为返回参数,该字段将会被添加到右侧的返回参数中。
说明将字段设置为返回参数后,您可以在右侧单击返回参数,设置字段信息。
添加到字段排序
单击字段后的添加,可以将该字段添加到排序字段区域,以进行排序。
排序字段
排序方式
向导模式
该字段的排序方式,支持升序和降序。
操作
可以单击上移或下移,对字段进行排序;单击移除,取消对该字段的排序。
编写查询SQL
脚本模式
输入SQL,然后单击自动解析参数,以生成请求参数和返回参数。
说明请求参数和返回参数生成后,您可以在右侧单击请求参数或返回参数,设置字段信息。
可选:设置API的执行属性。
单击页面右侧的属性,然后配置属性参数。
参数
说明
协议
调用API时使用的协议,支持HTTPS和SSE。
最大返回记录数
调用API时最多可返回的记录数量。
超时时间
调用API时的超时时间。
返回字段元数据
调用API是否返回元数据信息。
单击API信息上方的保存,保存API。

测试API
发布API
克隆API
修改API
删除API
当您不再需要某个API时,可以执行如下操作删除该API。
若该API已发布至线上,需先将其下线。
将鼠标指针放在目标API上,然后单击目标API后出现的
。单击删除。
在弹出的删除对话框,单击确认删除。

编辑目录
将鼠标指针放在目标目录上,然后单击目标目录后出现的
。单击编辑。
在弹出的编辑目录对话框,修改目录信息。
单击确认。

删除目录
当您的需要某个目录中无上线的API,且无需保留该目录时,可以执行如下操作删除该目录。
将鼠标指针放在目标目录上,然后单击目标目录后出现的
。单击删除。
说明请确保该目录中无上线的(服务状态为服务中)API。
在弹出的删除对话框,单击确认删除。
服务管理
服务管理页签展示了已发布至线上,或已下线且未删除的API。
进入服务开发页签
登录数据管理DMS 5.0。
在顶部菜单栏中,选择。
说明若您使用的是极简模式的控制台,请单击控制台左上角的
图标,选择。单击服务管理页签。
API授权
在当前页签的左侧导航栏,单击API管理。
在API管理页面中,单击目标API操作列的授权。

在弹出的授权对话框,选择授权账号并单击确认。

API下线
在当前页签的左侧导航栏,单击API管理。
在API管理页面中,单击目标API操作列的下线。
说明API下线后,该API的服务状态将变更为已停止。

API上线
在当前页签的左侧导航栏,单击API管理。
在API管理页面中,单击目标API操作列的上线。
说明API上线成功后,该API的服务状态将变更为服务中。

API测试
在当前页签的左侧导航栏,单击API测试。
在API测试区域,选择目标API。
在请求参数区域,填入请求参数的值。
单击开始测试。
当API调用成功后,在返回内容区域查看是否符合预期。

API调用
在当前页签的左侧导航栏,单击API调用。
查看API的调用信息,根据实际业务情况调用API。
API删除
若该API已发布至线上,需先将其下线。
在当前页签的左侧导航栏,单击API管理。
在API管理页面中,单击目标API操作列的删除。
在弹出的删除对话框,单击确认删除。

附录
支持的数据源
MySQL
包含RDS MySQL、本地自建MySQL和他云MySQL数据库。
PolarDB MySQL版
字段信息
脚本模式生成的请求参数和返回参数,无示例值、默认值和描述。
类型 | 参数 | 说明 |
请求参数 | 参数名称 | 调用API时的入参名称。 支持英文、数字、下划线(_)、短划线(-),且只能以英文或下划线(_)开头,1~50个字符,默认为字段名。 |
绑定字段 | 该字段的来源,即该字段对应的数据源中字段的名称。 | |
参数类型 | 该字段的数据类型,支持STRING(字符串类型)、NUMBER(数字类型,包含整数,浮点数等)、BOOLEAN(布尔类型)、ARRAY(数组类型,元素可为字符串、数字和布尔类型)。 | |
操作符 | 过滤条件的操作符,与参数名称和参数的取值共同过滤数据。 | |
是否必填 | 该字段是否为必传参数。 | |
示例值 | 该字段的取值示例。 | |
默认值 | 该字段的默认取值。 | |
描述 | 该字段的描述信息。 | |
返回参数 | 别名 | 返回参数名称。 支持英文、数字、下划线(_)、短划线(-),且只能以英文或下划线(_)开头,1~50个字符,默认为字段名。 |
绑定字段 | 该字段的来源,即该字段对应的数据源中字段的名称。 | |
参数类型 | 该字段的数据类型,支持STRING(字符串类型)、NUMBER(数字类型,包含整数,浮点数等)、BOOLEAN(布尔类型)、ARRAY(数组类型,元素可为字符串、数字和布尔类型)。 | |
示例值 | 该字段的返回值示例。 | |
默认值 | 该字段的默认返回值。 | |
描述 | 该字段的描述信息。 |
支持的SQL
形式 | 说明 | 示例 |
普通SQL | 使用 | |
分页参数 | 支持两种格式:
| |
if标签 | 在调用API时,只有当if语句中的条件满足时,该参数才会被添加至查询条件中。 | |
choose标签 | 多个条件分支,任意一个条件满足时,该参数就会被添加至查询条件中。 | |
where标签 | 多个条件分支,所有条件都满足时,该参数才会被添加至查询条件中。 | |
foreach标签 | 请求参数为列表类型。 重要 此时需手动调整请求参数中 | |
调用示例
可通过 Java 代码对已部署的数据服务 API 发起调用,兼容HTTPS与SSE两种通信协议,以下示例基于 Java 11 及以上版本,所需依赖如下
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.60</version>
</dependency>请求结构
无论是通过 HTTPS 还是 SSE 协议调用,请求体的结构是相同的。
{
"accessKey" : "xxx", #必填,DMS内凭证 AccessKey
"accessSecret" : "xxx", #必填,DMS内凭证 AccessKey
"query" : "call api ${apiPath}", # 必填,${apiPath}替换为api的路径
"params" : { # 选填,根据参数实际数据类型填写
"key1": value1,
"key2": value2
}
}参数名 | 类型 | 是否必填 | 说明 |
| String | 是 | 您在 DMS 内生成的凭证 AccessKey。 |
| String | 是 | 您在 DMS 内生成的凭证 AccessSecret。 |
| String | 是 | 固定格式为 |
| Object | 否 | 一个 JSON 对象,包含调用该 API 所需的所有请求参数及其值的键值对。若 API 无需参数,则此字段可省略。 重要 在 params 中,key都需要用双引号包裹,value应严格按实际数据类型书写,如字符串需用双引号包裹("abc"),数字、布尔值(true/false)均不加引号。 |
Https协议调用数据服务
适用于需要一次性获取完整结果集的标准查询场景。
import com.alibaba.fastjson.JSON;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
public class HttpsCallDataServiceApi {
private static final HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofSeconds(10))
.build();
public static void main(String[] args) {
try {
String response = callDmsApi();
System.out.println("响应内容: " + response);
} catch (Exception e) {
System.err.println("请求失败: " + e.getMessage());
e.printStackTrace();
}
}
public static String callDmsApi() throws Exception {
// 替换为各region具体的服务地址,具体可见数据服务首页
String url = "https://onequery-cn-hangzhou.proxy.dms.aliyuncs.com/service/http";
Map<String, Object> requestBody = new HashMap<>();
// 将 ${accessKey}、${accessSecret} 替换为用户的凭证信息,即DMS内部的凭证,而非RAM AK
requestBody.put("accessKey", "${accessKey}");
requestBody.put("accessSecret", "${accessSecret}");
// 替换 ${apiPath} 为具体的api路径
requestBody.put("query", "call api ${apiPath}");
// 构建 params,若参数为空,则无需传递此参数
Map<String, Object> params = new HashMap<>();
// 在实际调用中,需将${param}替换为实际的参数
// 数字类型参数
params.put("userId", 111);
// 字符串类型参数
params.put("name", "abc");
// 布尔类型参数
params.put("isActive", true);
// 列表类型参数
params.put("tags", Arrays.asList(1, 2, 3));
// 若参数为空,则无需put
requestBody.put("params", params);
String jsonBody = JSON.toJSONString(requestBody);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json;charset=utf-8")
.method("POST", HttpRequest.BodyPublishers.ofString(jsonBody))
.timeout(Duration.ofSeconds(30))
.build();
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
// 检查响应状态码
if (response.statusCode() != 200) {
throw new RuntimeException("HTTP error code: " + response.statusCode());
}
return response.body();
}
}调用成功后,会返回一个包含完整结果集的 JSON 对象。
字段 | 类型 | 说明 |
| String | 结果类型。 |
| String | 本次查询的唯一 ID,可用于问题排查。 |
| Number | 结果集中的数据行数。 |
| Array | 结果集数据。每个元素是一个代表数据行的 JSON 对象。 |
| Array | 字段元数据信息列表。 |
| Object | 查询相关的附加属性,如执行耗时 |
| String | 当 |
{
"attributes": {
"QueryTime": 13
},
"columnMetas": [
{
"autoIncrement": true,
"catalogName": "test_schema",
"columnLabel": "id",
"columnName": "id",
"columnTypeName": "BIGINT UNSIGNED",
"nullable": false,
"precision": 20,
"scale": 0,
"schemaName": "",
"tableName": "test_table"
},
{
"autoIncrement": false,
"catalogName": "test_schema",
"columnLabel": "gmt_create",
"columnName": "gmt_create",
"columnTypeName": "DATETIME",
"nullable": true,
"precision": 19,
"scale": 0,
"schemaName": "",
"tableName": "test_table"
}
],
"count": 1,
"message": null,
"rows": [
{
"id": 1,
"gmt_create": "2025-12-17 16:23:53"
}
],
"sessionId": 1560935281,
"traceId": "HZ1560935281OCQJOTKW",
"type": "RESULTSET"
}SSE协议调用数据服务
适用于长查询或需要逐步获取结果的场景。客户端将收到一个包含多个事件的消息流。
import com.alibaba.fastjson.JSON;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class SseCallDataServiceApi {
private static final HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.connectTimeout(Duration.ofSeconds(10))
.build();
public static void main(String[] args) {
try {
callDmsApiSse();
} catch (Exception e) {
System.err.println("SSE 请求失败: " + e.getMessage());
e.printStackTrace();
}
}
public static void callDmsApiSse() throws Exception {
// 替换为各region具体的服务地址,具体可见数据服务首页
String url = "https://onequery-cn-hangzhou.proxy.dms.aliyuncs.com/service/sse";
Map<String, Object> requestBody = new HashMap<>();
// 将 ${accessKey}、${accessSecret} 替换为用户的凭证信息,即DMS内部的凭证,而非RAM AK
requestBody.put("accessKey", "${accessKey}");
requestBody.put("accessSecret", "${accessSecret}");
// 替换 ${apiPath} 为具体的api路径
requestBody.put("query", "call api ${apiPath}");
// 构建 params,若参数为空,则无需传递该参数
Map<String, Object> params = new HashMap<>();
// 在实际调用中,需将${param}替换为实际的参数
// 数字类型参数
params.put("userId", 111);
// 字符串类型参数
params.put("name", "abc");
// 布尔类型参数
params.put("isActive", true);
// 列表类型参数
params.put("tags", Arrays.asList(1, 2, 3));
// 若参数为空,则无需put
requestBody.put("params", params);
String jsonBody = JSON.toJSONString(requestBody);
// 构建 HttpRequest,添加 SSE 必要的 Header
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json;charset=utf-8")
.header("Accept", "text/event-stream") // 指定接受 SSE 流
.header("Cache-Control", "no-cache")
.method("POST", HttpRequest.BodyPublishers.ofString(jsonBody))
.timeout(Duration.ofMinutes(5)) // SSE 通常是长连接,超时时间设长一点
.build();
// 发送请求并使用 ofLines 处理流式响应
System.out.println("开始接收 SSE 流...");
httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofLines())
.thenAccept(response -> {
if (response.statusCode() != 200) {
System.err.println("HTTP 错误: " + response.statusCode());
return;
}
// 逐行解析响应内容
try (Stream<String> lines = response.body()) {
lines.forEach(line -> {
if (line.startsWith("data:")) {
// 提取 data: 之后的内容
String data = line.substring(5).trim();
System.out.println("收到数据: " + data);
} else if (line.startsWith("error:")) {
System.err.println("收到错误: " + line);
}
});
}
})
.join(); // 为了演示效果,主线程等待异步执行完成
}
}SSE 响应是一个事件流,每个事件都以 data: 开头,其后跟随一个 JSON 对象。您需要关注该 JSON 对象中的 type 字段来判断事件类型。
| 事件类型 | 描述 |
| 元数据事件 | 流的第一个有效事件,包含结果集的字段元数据信息。 |
| 数据行事件 | 包含一批(或一行)结果数据。一个查询可能会触发多次 |
| 结束事件 | End-Of-File,标志着所有数据已发送完毕。 |
| 错误事件 | 查询过程中发生错误,此事件将包含详细的错误信息。 |
各类事件的 JSON 示例:
META 事件:
{ "attributes": { "QueryTime": 13 }, "columnMetas": [ { "autoIncrement": true, "catalogName": "test_schema", "columnLabel": "id", "columnName": "id", "columnTypeName": "BIGINT UNSIGNED", "nullable": false, "precision": 20, "scale": 0, "schemaName": "", "tableName": "test_table" }, { "autoIncrement": false, "catalogName": "test_schema", "columnLabel": "gmt_create", "columnName": "gmt_create", "columnTypeName": "DATETIME", "nullable": true, "precision": 19, "scale": 0, "schemaName": "", "tableName": "test_table" } ], "message": null, "resultIndex": 1, "sessionId": 1560946281, "traceId": "HZ1560946281OGMJSFEX", "type": "META" }ROWS 事件:
{ "attributes": {}, "count": 1, "message": null, "resultIndex": 1, "rows": [ [ 1, "2025-12-17 16:23:53" ] ], "sessionId": 1560946281, "traceId": "HZ1560946281OGMJSFEX", "type": "ROWS" }EOF 事件:
{ "attributes": { "TotalRowCount": 1 }, "lastResult": true, "message": null, "resultIndex": 1, "sessionId": 1560946281, "traceId": "HZ1560946281OGMJSFEX", "type": "EOF" }ERROR 事件:
{ "attributes": {}, "message": "[3050: Building Plan Error] PlanDAG build failed: The API does not exist. Publish it and try again.", "sessionId": 1560944281, "traceId": "HZ1560944281VWJLYLAK", "type": "ERROR" }



。




