API可使用SDK调用方式及白名单免密调用方式。其中仅使用私有网关的时候支持白名单方式。本篇API调用示例为调用模板,您可根据模板配置API的调用示例。
SDK调用
Java SDK简介
Dataphin数据服务Java SDK为您提供了快速调用数据服务API的基础SDK及示例调用代码。这里向您介绍如何使用Dataphin服务Java SDK。
Java SDK的代码文件层级结构如下:
JAR包版本可能跟随SDK的升级而升级。
Java SDK/
demo/
CallApiDemo.java
这里提供了同步API的调用示例和方法。CallAsyncApiDemo.java
这里提供了异步API的调用示例和方法。
lib/
dataphin-sdk-core-java-v5.2.0.jar
本SDK的依赖包。dataphin-sdk-core-java-v5.2.0-javadoc.jar
上述依赖包的Javadoc。dataphin-sdk-core-java-v5.2.0-jar-with-dependencies.jar
上述依赖包的全依赖包。
ApiDocument_v5.2.0.md
API接口文档。LICENSE
许可证。
Java SDK获取方式如下:
在Dataphin首页的顶部菜单栏,选择服务 > 调用。
在左侧导航栏单击调用说明。
单击API调用说明页签,在页面右上方选择Java SDK下载,将下载SDK的Jar包添加至pom.xml中。
Java SDK调用同步API流程
在调用API之前,您首先需要初始化客户端。
若API的响应时间较长,可使用异步调用,在整个等待应答期间,主线程不会被阻塞。
您可以实例化QueryParamRequest对象,并且设置请求参数满足不同的查询需要,详情请参考调用实例中的packRequestParam方法。
API请求和返回结果信息请查看SDK中的APIDocument.md。
若在使用中遇到问题,请咨询Dataphin技术支持。
步骤一:环境准备
Dataphin服务Java SDK适用于JDK 1.6及以上版本。
您需要准备一对授权密钥供SDK生成鉴权和签名信息,即AppKey和AppSecret。
AppKey和AppSecret可在服务 > 调用 > 应用管理列表中获取。
重要AppKey和AppSecret是Dataphin数据服务认证用户请求的密钥,这两个配置如果保存在客户端,请妥善加密。
在
pom.xml
中添加如下依赖,如果添加dataphin-sdk-core-java
报错请手动添加该JAR文件,路径JAVA_SDK/lib/dataphin-sdk-core-java-v5.2.0.jar
(即所获取Java SDK中的JAR包)。说明dataphin-sdk-core-java
并不存在于中央Maven仓库,因此下载该SDK后还需要您上传至贵公司的Maven仓库,或者在IDEA、Eclipse中手动引入。<dependency> <groupId>com.alibaba.dt</groupId> <artifactId>dataphin-sdk-core-java</artifactId> <version>v5.2.0</version> </dependency>
步骤二:引入Java SDK的API接口调用类
在服务 > 市场 > API服务列表中下载对应的API文档。
导入
CallApiDemo.java
,修正CallApiDemo.java
类的import和package。/* * Copyright 2018 Alibaba.com All right reserved. This software is the confidential and proprietary * information of Alibaba.com ("Confidential Information"). You shall not disclose such Confidential * Information and shall use it only in accordance with the terms of the license agreement you * entered into with Alibaba.com. */ import java.util.HashMap; import java.util.List; import com.alibaba.cloudapi.sdk.constant.SdkConstant; import com.alibaba.cloudapi.sdk.enums.Scheme; import com.alibaba.cloudapi.sdk.model.ApiResponse; import com.alibaba.dt.dataphin.client.ApiClient; import com.alibaba.dt.dataphin.client.ApiClientBuilderParams; import com.alibaba.dt.dataphin.schema.OrderBy; import com.alibaba.dt.dataphin.schema.QueryParamRequest; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import static com.alibaba.cloudapi.sdk.constant.SdkConstant.CLOUDAPI_LF; public class CallApiDemo { /** * 访问域名或ip,在数据服务的网络配置中获得该值 */ private static final String HOST = "xxx"; /** * 应用appKey,即你用哪个APP来调用这个API */ private static final String APP_KEY = "xxx"; /** * 应用appSecret,即你用哪个APP来调用这个API */ private static final String APP_SECRET = "xxx"; /** * 配置调用的API编号 */ private static final String API_ID = "xxx"; public static void main(String[] args) throws Exception { // 同步调用GET类型API syncGet(); // 同步调用LIST类型API syncList(); // 异步调用GET类型API asyncGet(); // 异步调用LIST类型API asyncList(); } public static void syncGet() throws Exception { // 获取 ApiClient 对象 ApiClient client = getClient(); // 需要按需修改里面的返回字段、查询条件等 QueryParamRequest queryParamRequest = packRequestParam(); ApiResponse response = client.getSync(API_ID, queryParamRequest); System.out.println(getResultString(response)); } public static void syncList() throws Exception { // 获取 ApiClient 对象 ApiClient client = getClient(); // 需要按需修改里面的返回字段、查询条件等 QueryParamRequest queryParamRequest = packRequestParam(); ApiResponse response = client.listSync(API_ID, queryParamRequest); System.out.println(getResultString(response)); } public static void asyncGet() throws Exception { // 获取 ApiClient 对象 ApiClient client = getClient(); // 需要按需修改里面的返回字段、查询条件等 QueryParamRequest queryParamRequest = packRequestParam(); client.getAsync(API_ID, queryParamRequest, new ApiCallback() { @Override public void onFailure(ApiRequest request, Exception e) { e.printStackTrace(); } @Override public void onResponse(ApiRequest request, ApiResponse response) { try { System.out.println(getResultString(response)); } catch (Exception e) { e.printStackTrace(); } } }); System.out.println("--- main线程提前结束 ---"); } public static void asyncList() throws Exception { // 获取 ApiClient 对象 ApiClient client = getClient(); // 需要按需修改里面的返回字段、查询条件等 QueryParamRequest queryParamRequest = packRequestParam(); client.listAsync(API_ID, queryParamRequest, new ApiCallback() { @Override public void onFailure(ApiRequest request, Exception e) { e.printStackTrace(); } @Override public void onResponse(ApiRequest request, ApiResponse response) { try { System.out.println(getResultString(response)); } catch (Exception e) { e.printStackTrace(); } } }); System.out.println("--- main线程提前结束 ---"); } private static ApiClient getClient() { ApiClientBuilderParams params = new ApiClientBuilderParams(); // 应用appKey params.setAppKey(APP_KEY); // 应用appSecret params.setAppSecret(APP_SECRET); // 访问域名或ip params.setHost(HOST); // 默认为HTTP协议,如果API支持HTTPS,这里也可以设置HTTPS params.setScheme(Scheme.HTTP); // stage环境变量:PRE指定开发环境API、RELEASE指定生产环境API params.setStage("RELEASE"); // 如果使用二级域名或未指定环境的独立域名,需要设置env // 有 PROD 和 PRE 两种值(如果是basic模式,传PROD; 如果是Dev-Prod模式,PROD表示查生产环境数据,PRE表示查开发环境数据) // 如果已经指定了访问环境的独立域名,则env参数不会起作用 params.setEnv("PROD"); return new ApiClient(params); } private static QueryParamRequest packRequestParam() { QueryParamRequest queryParamRequest = new QueryParamRequest(); /********* API相关业务参数设置 begin *********/ /* * 代理账号类型,非必填 * 注意,若要使用代理模式,需同时满足以下条件: * 1. 开通行级权限功能 * 2. 应用申请了代理权限 * 3. API设置了关联的行级权限 * * 当使用代理模式认证时,需要指定代理用户的账号类型。 * ACCOUNT_NAME:Dataphin的用户名。 * USER_ID:Dataphin内部的唯一ID。 * SOURCE_USER_ID:源系统账号ID。 * 仅当设置了DelegationUid时,需要配置此参数。若未填写此参数,则默认类型为USER_ID。 */ queryParamRequest.setAccountType("USER_ID"); /* * 代理账号ID,非必填 * 被代理访问的用户,需根据所选AccountType的类型,传入对应账号ID。 * 设置该参数且API设置了关联的行级权限规则,会使用代理模式的认证方式。 */ queryParamRequest.setDelegationUid("abcd"); /* * 请求参数列表,非必填的参数可不传,必填参数必须传,否则会报错 * 其中key为对应的查询字段,value为查询字段对应的值 * 例如这里的id为请求字段名,1为id对应的值,可以设置多个查询参数 * 注意:如果是 IN 类型的参数,使用 List 包装参数值 */ HashMap<String, Object> conditions = Maps.newHashMap(); conditions.put("id", 1); conditions.put("age", Lists.newArrayList(10,20,30)); queryParamRequest.setConditions(conditions); /* * 返回参数列表,不能为空 * 例如指定返回id和name * 注意:返回参数如果不存在或没权限会报错 */ queryParamRequest.setReturnFields(Lists.newArrayList("id", "name")); /* * 排序字段,非必填 * 注意oracle和sqlServer使用分页需要同时使用排序 * 指定参数升序或者降序,可设置多个字段进行升序或者降序 * 例如返回结果按id进行升序 */ List<OrderBy> orderList = Lists.newArrayList(); orderList.add(new OrderBy("id1", OrderBy.Order.ASC)); orderList.add(new OrderBy("id2", OrderBy.Order.DESC)); queryParamRequest.setOrderBys(orderList); /* * 分页参数,非必填,仅LIST类型API生效 */ // 从第几条数据取 queryParamRequest.setPageStart(0); // 每页取多少条数据 queryParamRequest.setPageSize(10); /* * API版本号,非必填,仅开发环境支持设置 */ queryParamRequest.setApiVersion("V1"); /********* API相关业务参数设置 end *********/ /********* 功能参数设置 begin *********/ /* * 是否使用模型缓存 * 开启会减少同一个服务单元API相同出入参时的解析频次,提高查询效率 */ queryParamRequest.setUseModelCache(Boolean.getBoolean("false")); /* * 是否使用结果缓存 * 开启则会缓存同一个API相同条件、相同返回字段的查询结果 * 适用于数据不变化的查询,减少相同SQL的查询频次,提高查询效率 * 缓存时长默认30分钟,3.5.6 版本后,在API开发页面可设置缓存时长 * 注意:如果API未开启结果缓存,该参数无效 */ queryParamRequest.setUseResultCache(Boolean.getBoolean("false")); /* * 是否保持字段的大小写格式 * 如果对大小写敏感,建议设置为true * 为false时,直连API返回结果的字段名默认为大写字母 */ queryParamRequest.setKeepColumnCase(true); /********* 功能参数设置 end *********/ return queryParamRequest; } private static String getResultString(ApiResponse response) { StringBuilder result = new StringBuilder(); result.append("ResultCode:").append(CLOUDAPI_LF).append(response.getCode()).append(CLOUDAPI_LF); result.append("RequestId:").append(response.getHeaders().get("x-ca-request-id")).append(CLOUDAPI_LF); result.append("ErrorCode:").append(response.getHeaders().get("x-ca-error-code")).append(CLOUDAPI_LF); if (200 != response.getCode()) { result.append("Error:").append(response.getHeaders().get("x-ca-error-message")).append(CLOUDAPI_LF); } result.append("ResultBody:").append(CLOUDAPI_LF).append(new String(response.getBody(), SdkConstant.CLOUDAPI_ENCODING)); return result.toString(); }
步骤三:初始化通信通道类
要调用API,首先要初始化客户端。您可以参考ClientDemo.java
中的示例代码,使用对应的ApiClientBuilderParams
类来进行初始化。其中,需要把Host、APP_Key和APP_Secret三个变量替换为用户的真实数据。
步骤四:API接口说明
API接口类型
API接口类型分为LIST和GET,LIST支持分页查询而GET不支持,请参考
CallApiDemo.java
中的packRequestParam方法, 设置QueryParamRequest里的参数。调用API接口
SDK中的LIST和GET方法为Dataphin数据服务的通用方法,SDK中提供同步和异步的调用方法。在调用API之前,您需要根据您在Dataphin数据服务中定义的API填入相关的请求参数。
调试用例中condition为业务请求参数,returnFields为API的返回参数,具体参数请参考服务 > 调用 > 已授权API服务页面,单击目标API操作列下调试,进入调试页面。
请求参数中的API_ID,请参考服务 > 调用 > 已授权API服务页面API列下的API_ID。
Java SDK调用异步API流程
在调用API之前,您首先需要初始化客户端。
若API的响应时间较长,可使用异步调用,在整个等待应答期间,主线程不会被阻塞。
您可以实例化QueryParamRequest对象,并且设置请求参数满足不同的查询需要,详情请参考调用实例中的packRequestParam方法。
API请求和返回结果信息请查看SDK中的APIDocument.md。
若在使用中遇到问题,请咨询Dataphin技术支持。
步骤一:环境准备
Dataphin服务Java SDK适用于JDK 1.6及以上版本。
您需要准备一对授权密钥供SDK生成鉴权和签名信息,即AppKey和AppSecret。
AppKey和AppSecret可在服务 > 调用 > 应用管理列表中获取。
重要AppKey和AppSecret是Dataphin服务认证用户请求的密钥,这两个配置如果保存在客户端,请妥善加密。
在pom.xml中添加如下依赖,如果添加
dataphin-sdk-core-java
报错请手动添加该jar文件,路径JAVA_SDK/lib/dataphin-sdk-core-java-v5.2.0.jar
(即所获取Java SDK中的Jar包)。说明dataphin-sdk-core-java
并不存在于中央Maven仓库,因此下载该SDK后还需要您上传至贵公司的Maven仓库,或者在IDEA、Eclipse中手动引入。<dependency> <groupId>com.alibaba.dt</groupId> <artifactId>dataphin-sdk-core-java</artifactId> <version>v5.2.0</version> </dependency>
步骤二:引入Java SDK的API接口调用类
在服务 > 市场 > API服务列表中下载对应的API文档。
导入
CallAsyncApiDemo.java
,修正CallAsyncApiDemo.java
类的import和package。/* * Copyright 2018 Alibaba.com All right reserved. This software is the confidential and proprietary * information of Alibaba.com ("Confidential Information"). You shall not disclose such Confidential * Information and shall use it only in accordance with the terms of the license agreement you * entered into with Alibaba.com. */ import com.alibaba.cloudapi.sdk.enums.Scheme; import com.alibaba.cloudapi.sdk.model.ApiRequest; import com.alibaba.dt.dataphin.client.ApiClientBuilderParams; import com.alibaba.dt.dataphin.client.DataphinDataServiceException; import com.alibaba.dt.dataphin.client.async.AsyncApiCallBack; import com.alibaba.dt.dataphin.client.async.AsyncApiClient; import com.alibaba.dt.dataphin.client.async.AsyncJobContext; import com.alibaba.dt.dataphin.schema.AsyncQueryResults; import com.alibaba.dt.dataphin.schema.OrderBy; import com.alibaba.dt.dataphin.schema.QueryParamRequest; import com.alibaba.fastjson.JSONObject; import com.google.common.base.Splitter; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class CallAsyncApiDemo { /** * 访问域名或ip,在数据服务的网络配置中获得该值 */ private static final String HOST = "xxx"; /** * 应用appKey,即你用哪个APP来调用这个API */ private static final String APP_KEY = "xxx"; /** * 应用appSecret,即你用哪个APP来调用这个API */ private static final String APP_SECRET = "xxx"; /** * 配置调用的API编号 */ private static final String API_ID = "xxx"; /** * 每批次查询条数,默认1000条 */ private static final Integer FETCH_SIZE = 1000; public static void main(String[] args) throws Exception { // 阻塞式调用 callAsyncApiBlock(); // 非阻塞式调用 callAsyncApiNotBlock(); } /** * 阻塞式调用 */ @SuppressWarnings("all") private static void callAsyncApiBlock() { // 获取 AsyncApiClient 对象 AsyncApiClient asyncApiClient = getClient(); // 需要按需修改里面的返回字段、查询条件等 QueryParamRequest queryParamRequest = packRequestParam(); AsyncQueryResults asyncQueryResults = asyncApiClient.listAsyncWaitFinish(API_ID, queryParamRequest); System.out.println(JSONObject.toJSONString(asyncQueryResults)); // 关闭客户端,回收资源 asyncApiClient.shutdown(); } /** * 非阻塞式调用 */ @SuppressWarnings("all") private static void callAsyncApiNotBlock(){ // 获取 AsyncApiClient 对象 AsyncApiClient asyncApiClient = getClient(); // 需要按需修改里面的返回字段、查询条件等 QueryParamRequest queryParamRequest = packRequestParam(); try { AsyncApiCallBack callback = new AsyncApiCallBack() { @Override public void onFailure(ApiRequest request, DataphinDataServiceException e) { System.out.println(e.getMessage()); } @Override public void onResponse(ApiRequest request, AsyncQueryResults results) { System.out.println(JSONObject.toJSONString(results)); } }; AsyncJobContext context = asyncApiClient.listAsync(API_ID, queryParamRequest, callback); // 请求成功会返回本次请求的jobId System.out.printf("jobId: %s", context.getJobId()); // 等待运行结束,真实场景请勿使用sleep方式等待 Thread.sleep(600000); } catch (Exception e) { e.printStackTrace(); } // 关闭客户端,回收资源 asyncApiClient.shutdown(); } private static AsyncApiClient getClient() { ApiClientBuilderParams params = new ApiClientBuilderParams(); // 应用appKey params.setAppKey(appKey); // 应用appSecret params.setAppSecret(appSecret); // 访问域名或ip params.setHost(HOST); // 默认为http协议, 可根据API设置https协议 // 注意:Dataphin内置网关不支持https,阿里云API网关支持https params.setScheme(Scheme.HTTP); // 每批次查询条数,默认1000条 params.setFetchSize(FETCH_SIZE); // stage环境变量:PRE指定开发环境API、RELEASE指定生产环境API params.setStage("RELEASE"); // 如果使用二级域名或未指定环境的独立域名,需要设置env // 有 PROD 和 PRE 两种值(如果是basic模式,传PROD; 如果是Dev-Prod模式,PROD表示查生产环境数据,PRE表示查开发环境数据) // 如果已经指定了访问环境的独立域名,则env参数不会起作用 params.setEnv("PROD"); return new AsyncApiClient(params); } private static QueryParamRequest packRequestParam() { QueryParamRequest queryParamRequest = new QueryParamRequest(); /********* API相关业务参数设置 begin *********/ /* * 代理账号类型,非必填 * 注意,若要使用代理模式,需同时满足以下条件: * 1. 开通行级权限功能 * 2. 应用申请了代理权限 * 3. API设置了关联的行级权限 * * 当使用代理模式认证时,需要指定代理用户的账号类型。 * ACCOUNT_NAME:Dataphin的用户名。 * USER_ID:Dataphin内部的唯一ID。 * SOURCE_USER_ID:源系统账号ID。 * 仅当设置了DelegationUid时,需要配置此参数。若未填写此参数,则默认类型为USER_ID。 */ queryParamRequest.setAccountType("USER_ID"); /* * 代理账号ID,非必填 * 被代理访问的用户,需根据所选AccountType的类型,传入对应账号ID。 * 设置该参数且API设置了关联的行级权限规则,会使用代理模式的认证方式。 */ queryParamRequest.setDelegationUid("abcd"); /* * 请求参数列表,非必填参数可不传,必填参数必须传,否则会报错 * 其中key为对应的查询字段,value为查询字段对应的值 * 例如这里的id为请求字段名,1为id对应的值,可以设置多个查询参数 * 注意:如果是 IN 类型的参数,使用 List 包装参数值,例如这里的age */ HashMap<String, Object> conditions = Maps.newHashMap(); conditions.put("id", 1); conditions.put("age", Lists.newArrayList(10,20,30)); queryParamRequest.setConditions(conditions); /* * 返回参数列表,必填 * 例如指定返回id和name * 注意:返回参数如果不存在或没权限会报错 */ queryParamRequest.setReturnFields(Lists.newArrayList("id", "name")); /* * 排序字段,非必填 * 注意oracle和sqlServer使用分页需要同时使用排序 * 指定参数升序或者降序,可设置多个字段进行升序或者降序 * 例如返回结果按id进行升序 */ List<OrderBy> orderList = Lists.newArrayList(); orderList.add(new OrderBy("id1", OrderBy.Order.ASC)); orderList.add(new OrderBy("id2", OrderBy.Order.DESC)); queryParamRequest.setOrderBys(orderList); /* * API版本号,非必填,仅开发环境支持设置 */ queryParamRequest.setApiVersion("V1"); /********* API相关业务参数设置 end *********/ /********* 功能参数设置 begin *********/ /* * 是否保持字段的大小写格式,固定传true */ queryParamRequest.setKeepColumnCase(true); /********* 功能参数设置 end *********/ return queryParamRequest; } }
步骤三:初始化通信通道类
要调用API,首先要初始化客户端。您可以参考CallAsyncApiDemo.java
中的示例代码,使用对应的ApiClientBuilderParams
类来进行初始化。其中,需把Host、APP_Key和APP_Secret三个变量替换为用户的真实数据。
步骤四:API接口说明
API接口类型
API接口类型分为LIST和GET,LIST支持分页查询而GET不支持,请参考CallAsyncApiDemo.java中的packRequestParam方法, 设置QueryParamRequest里的参数。
调用API接口
SDK中的LIST和GET方法为Dataphin数据服务的通用方法,SDK中同时提供同步和异步的调用方法。在调用API之前,您需要根据您在Dataphin数据服务定义的API填写相关的请求参数。
调试用例中condition为业务请求参数,returnFields为API的返回参数,具体参数请参考服务 > 调用 > 已授权API服务页面,单击目标API操作列下调试,进入调试页面。
请求参数中的API_ID,请参考服务 > 调用 > 已授权API服务页面API列下的API_ID。
Python SDK调用流程
步骤一:环境准备
Python SDK适用于Python3.9及以上版本。
Python SDK获取方式如下:
在Dataphin首页的顶部菜单栏,选择服务 > 调用。
在左侧导航栏单击调用说明。
单击API调用示例页签,单击页面右上方的python调用示例下载按钮,获取Python SDK core包。
准备一对授权密钥供SDK生成鉴权和签名信息,即AppKey和AppSecret。
重要AppKey和AppSecret是Dataphin服务认证用户请求的密钥,这两个配置如果保存在客户端,请妥善加密。
准备一个JSON文件,格式如下:
{ "host": "API网关域名", "port": 80, "impalaConfig": { "pollingTimeout": 300, "pollingInterval": 800 }, "applicationConfig": { "appKey": "敏感数据自行填充", "appSecret": "敏感数据自行填充" }, "apiConfig": { "apiNo": 10008, "scheme": "HTTP", "stage": "RELEASE", "env": "PROD", "method": "LIST", "queryParamRequest": { "conditions": {"id": "1"}, // 请求参数列表,根据参数决定,非必填参数可不传,必填参数必须传 "returnFields": ["id", "name", "age"], // 返回参数列表,必填,返回参数如果不存在或没权限会报错 "orderBys": [{"field": "id", "order": "ASC"}], // 排序字段,非必填 "useModelCache": "false", // 是否使用模型缓存,开启会减少同一个服务单元API相同出入参时的解析频次,提高查询效率 "useResultCache": "false", // 是否使用结果缓存,开启则会缓存同一个API相同条件、相同返回字段的查询结果 "apiVersion": "V1", // API版本号,非必填,仅开发环境支持设置 "accountType": "USER_ID", // 代理账号类型,非必填,使用代理模式时需要配置此参数 "delegationUid": "abcd" // 代理账号ID,非必填,使用代理模式时需要配置此参数 } } }
步骤二:部署Python SDK
安装Python开发工具PyCharm。
打开Python项目。
在Demo类的启动参数上配置JSON文件路径。
具体调用请参照demo.py。
步骤三:调用API
在JSON文件中配置调用参数信息。
Python SDK通过读取JSON文件来组装API调用的基础参数。
调用apiClient.callApi方法,具体参照demo.py。
# -*- coding: utf-8 -*- import dataapi import sys with open(str(sys.argv[1]), encoding="utf-8") as f: json_obj = eval(f.read().replace('\n\u200b', '')) # 这里是读取上下文的json文件,假如不需要json文件的话,直接填写对应值的就好了 # 网关调用地址 host = json_obj["host"] # 网关调用端口 port = json_obj["port"] # 可不配置。只对impala类型的API有效,轮询超时时间 pollingTimeout = json_obj["impalaConfig"]["pollingTimeout"] # 可不配置。只对impala类型的API有效,轮询间隔 pollingInterval = json_obj["impalaConfig"]["pollingInterval"] # app的信息,你用哪个APP来调用这个API appKey = json_obj["applicationConfig"]["appKey"] appSecret = json_obj["applicationConfig"]["appSecret"] # api的信息 apiId = json_obj["apiConfig"]["apiNo"] # 用什么方式调用API? 值是:HTTP 或 HTTPS。注意私有网关只支持HTTP 【区分大小写】 scheme = json_obj["apiConfig"]["scheme"] # 生产环境:RELEASE,开发环境:PRE stage = json_obj["apiConfig"]["stage"] # 有 PROD 和 PRE 两种值 (如果是basic模式,传死PROD; 如果是Dev-Prod模式,PROD表示查生产库,PRE表示查开发库 【区分大小写】 env = json_obj["apiConfig"]["env"] # 请求参数,必填 queryParam = json_obj["apiConfig"]["queryParamRequest"] # API是 GET 还是 LIST? 【区分大小写】 method = json_obj["apiConfig"]["method"] if (host == None or host == ""): raise Exception("host信息缺失") if (appKey == None or appKey == ""): raise Exception("appKey信息缺失") if (appSecret == None or appSecret == ""): raise Exception("appSecret信息缺失") if (method == None or method == ""): raise Exception("method信息缺失") if (apiId == None or apiId == ""): raise Exception("apiNo信息缺失") # 配置impala impalaConfig = dataapi.ImpalaConfig(pollingTimeout=pollingTimeout, pollingInterval=pollingInterval) # 配置app appConfig = dataapi.AppConfig(appKey=appKey, appSecret=appSecret) apiConfig = dataapi.ApiConfig(apiId, scheme, stage, env, queryParam, method) myConfig = dataapi.MyConfig(host, port, impalaConfig, appConfig, apiConfig) apiClient = dataapi.ApiClient(myConfig) # 同步API请求 resp = apiClient.callApi(queryParam) print(resp) # 异步API请求 asyncResp = apiClient.asyncCallApi(queryParam) print(asyncResp)
白名单调用方式(仅私有化部署时支持)
通过配置白名单免密方式访问API的安全策略,可简化API调用流程。IP白名单策略为应用级别策略,目前仅私有云支持此方式调用。
开发流程
步骤一:后台配置
您需要在数据服务中创建API、应用、应用白名单以及将应用和API进行绑定,才能通过白名单方式访问API。
创建API:您可在服务 > 开发 > API页面,选择通过直连数据源模式、逻辑表API-SQL模式、逻辑表API-向导模式、注册API和组合API五种方式创建API,如何创建,请参见创建API。
创建应用及应用白名单:应用可用于调用生产环境的API,并可为API设置白名单,如何创建应用及白名单,请参见新建及管理服务应用。
应用和API绑定:需申请该API的所属应用权限才能使用该API,如何申请,请参见管理API权限。
步骤二:发起请求
请求类型:POST
只支持POST提交的请求,BODY一律使用JSON字符串,并且Content-Type设置为
application/octet-stream; charset=utf-8
。设置公共入参
参数名
位置
是否必填
示例
说明
accept
Header
是
application/json; charset=utf-8
响应格式。
host
Header
是
7229fc4974**
-cn-shanghai.alicloudapi.com。
x-ca-key
Header
是
2037**895
appkey,调用API的身份标识。
x-ca-stage
Header
是
RELEASE
环境标识,RELEASE访问生产环境、PRE访问开发环境。
Content-Type
Header
是
application/octet-stream; charset=utf-8
请求格式。
whitelist-flag
Header
是
1
白名单标识(非空)。
请求格式
URL:POST [host]/method/apiId?appKey=应用的AppKey&env=PROD
host:API网关域名(可在服务 > 管理 > 网络配置页面获取)。
method:API的请求方式,GET或者LIST(可在服务 > 调用> 已授权API服务 > 调试页面获取)。
apiId:API的唯一标识(可在服务 > 调用> 已授权API服务 > 调试页面获取)。
appKey:该API绑定的应用的唯一标识(可在服务 > 调用 > 应用管理页面获取)
env:环境标识,PROD表示访问生产环境上的API,PRE表示访问开发环境的API。
请求URL示例:
gateway.aliyun.com/list/12345?appKey=xxx&env=PROD
。
使用PostMan调用示例
步骤一:请求地址
请求POST地址
[host]/method/apiId?appKey=应用的AppKey&env=PROD
。步骤二:填入Header
填入Header,可参考设置公共入参填写。
Header示例如下:
accept:application/json;charset=utf-8 x-ca-key:敏感数据自行填充 host:API网关域名 x-ca-stage:RELEASE Content-Type:application/octet-stream;charset=utf-8 whitelist-flag:1
步骤三:填入body
说明Content-Type使用
application/octet-stream; charset=utf-8
。body示例:
{ "conditions": {"id": "1"}, // 请求参数列表,根据参数决定,非必填参数可不传,必填参数必须传 "returnFields": ["id", "name", "age"], // 返回参数列表,必填,返回参数如果不存在或没权限会报错 "orderBys": [{"field": "id", "order": "ASC"}], // 排序字段,非必填 "useModelCache": "false", // 是否使用模型缓存,开启会减少同一个服务单元API相同出入参时的解析频次,提高查询效率 "useResultCache": "false", // 是否使用结果缓存,开启则会缓存同一个API相同条件、相同返回字段的查询结果 "apiVersion": "V1", // API版本号,非必填,仅开发环境支持设置 "accountType": "USER_ID", // 代理账号类型,非必填,使用代理模式时需要配置此参数 "delegationUid": "abcd" // 代理账号ID,非必填,使用代理模式时需要配置此参数 }
错误码
客户端错误
错误代码 | HTTP状态码 | 语义 | 解决方案 |
Throttled by APP Flow Control | 403 | 因APP流控被限制 | 调用频率过高导致被流控,可以联系服务提供方放宽限制。 |
Throttled by API Flow Control | 403 | 因API流控被限制 | 调用频率过高导致被流控,可以联系服务提供方放宽限制。 |
Throttled by DOMAIN Flow Control | 403 | 因二级域名流控被限制 | 直接访问二级域名调用API,每天被访问次数上限1000次。 |
TThrottled by GROUP Flow Control | 403 | 因分组流控被限制 | 调用频率过高导致被流控,可以联系服务提供方放宽限制。 |
Empty Request Body | 400 | body为空 | 请检查请求Body内容。 |
Invalid Request Body | 400 | body无效 | 请检查请求Body。 |
Invalid Param Location | 400 | 参数位置错误 | 请求参数位置错误。 |
Invalid Url | 400 | URL无效 | 请求的Method、Path或者环境不对。请参照错误说明Invalid URL。 |
Invalid Domain | 400 | 域名无效 | 请求域名无效,根据域名找不到API。请联系 Dataphin服务团队。 |
Invalid HttpMethod | 400 | HttpMethod无效 | 输入的Method不合法。 |
Invalid AppKey | 400 | AppKey无效或不存在 | 请检查传入的AppKey。注意左右空格的影响。 |
Invalid AppSecret | 400 | APP的Secret错误 | 检查传入的AppSecret。注意左右空格的影响。 |
Timestamp Expired | 400 | 时间戳过时 | 请核对请求系统时间是否为标准时间。 |
Invalid Timestamp | 400 | 时间戳不合法 | 请参照请求签名说明文档。 |
Empty Signature | 404 | 签名为空 | 请传入签名字符串,请参照请求签名说明文档。 |
Invalid Signature, Server StringToSign:%s | 400 | 签名无效 | 签名无效,参照Invalid Signature错误说明。 |
Invalid Content-MD5 | 400 | Content-MD5值不合法 | 请求Body为空,但传入了MD5值,或 MD5 值计算错误。请参照请求签名说明文档。 |
Unauthorized | 403 | 未被授权 | APP未获得要调用的API的授权。请参照错误说明Unauthorized。 |
Nonce Used | 400 | SignatureNonce已被使用 | x-ca-nonce不能被重复使用,重新生成x-ca-nonce。 |
API Not Found | 400 | 找不到API | 传入的API请求地址或者HttpMethod不正确,或已下线。 |
服务器端错误(调用 API)
以下为API服务端错误。
错误代码 | HTTP状态码 | 语义 | 解决方案 |
Internal Error | 500 | 内部错误 | 建议重试。 |
Failed To Invoke Backend Service | 500 | 底层服务错误 | API底层服务错误,建议重试。 |
Service Unavailable | 503 | 服务不可用 | 建议重试。 |
Async Service | 504 | 服务超时 | 建议重试。 |
服务器端错误(执行SQL语句)
错误代码 | 语义 |
DPN-OLTP-COMMON-000 | 成功。 |
DPN.Oltp.Common.Running | 运行中。 |
DPN-OLTP-COMMON-001 | 系统发生未知异常。 |
DPN-OLTP-COMMON-002 | 参数异常。 |
DPN-OLTP-COMMON-003 | 不支持。 |
DPN-OLTP-COMMON-004 | SQL解析异常。 |
DPN-OLTP-COMMON-005 | SQL注入检测未通过。 |
DPN-OLTP-ENGINE-000 | 查询超时。 |
DPN-OLTP-ENGINE-001 | 参数错误。 |
DPN-OLTP-ENGINE-002 | 对象找不到。 |
DPN-OLTP-ENGINE-003 | 不支持。 |
DPN-OLTP-ENGINE-004 | 通信表错误。 |
DPN-OLTP-ENGINE-005 | SQL解析失败。 |
DPN-OLTP-ENGINE-006 | 元数据错误。 |
DPN-OLTP-ENGINE-007 | 参数处理错误。 |
DPN-OLTP-ENGINE-008 | 构建执行模型错误。 |
DPN-OLTP-ENGINE-009 | 执行失败。 |
DPN-OLTP-ENGINE-010 | 数据源错误。 |
DPN-OLTP-ENGINE-011 | HBase引擎不支持。 |
DPN-OLTP-ENGINE-012 | 对象序列化失败。 |
DPN-OLTP-ENGINE-013 | 权限校验失败。 |
DPN-OLTP-ENGINE-014 | Elasticsearch引擎不支持。 |
DPN-OLTP-ENGINE-015 | MongoDB引擎不支持。 |
DPN-OLTP-ENGINE-016 | 字段类型错误。 |
DPN-OLTP-ENGINE-017 | Redis缓存异常。 |
DPN-OLTP-ENGINE-018 | 跨数据源不支持。 |
DPN-OLTP-ENGINE-018-01 | 跨数据源不支持Group by。 |
DPN-OLTP-ENGINE-018-02 | 跨数据源不支持Order by。 |
DPN-OLTP-ENGINE-018-03 | 跨数据源不支持没有where条件。 |
DPN-OLTP-ENGINE-018-04 | 跨数据源不支持page start不等于0。 |
DPN-OLTP-ENGINE-018-05 | 跨数据源不支持在where条件中存在or操作。 |
DPN-OLTP-ENGINE-018-06 | 跨数据源不支持在一个select item中有来自多个物理表的字段。 |
DPN-OLTP-ENGINE-018-07 | 跨数据源查询必须所有的主键都在。 |
DPN-OLTP-ENGINE-019 | 数据类型编码或者参数类型转换失败。 |
DPN-OLTP-ENGINE-20 | 熔断。 |
DPN-OLTP-ENGINE-21 | 限流。 |
DPN-OLTP-ENGINE-22 | 查询超时。 |
DPN-OLTP-ENGINE-23 | 组合API的子API异常。 |
DPN-OLTP-ENGINE-24 | 无代理权限。 |
DPN.Oltp.Auth | 权限校验失败。 |
DPN.Oltp.Async.JobNotExists | 异步API任务不存在。 |
DPN.Oltp.Async.JobStatusNotSupport | 异步API任务状态不支持该操作。 |
DPN.Oltp.Async.GetResultError | 异步API获取结果失败。 |
DPN.Oltp.Oltp.JsonContentParseError | JSON内容解析失败。 |
DPN.Oltp.Oltp.HttpRequestError | HTTP请求失败。 |
DPN.Oltp.Jdbc.ProjectForbidden | 无权修改该项目下的表。 |
DPN-OLTP-JDBC-001 | 请求头丢失Session。 |
DPN-OLTP-JDBC-002 | Session错误。 |
DPN-OLTP-JDBC-003 | 无权访问数据库。 |
DPN-OLTP-JDBC-004 | 无权访问数据表。 |
DPN-OLTP-JDBC-005 | AccountId错误。 |
DPN-OLTP-JDBC-006 | 终止查询。 |
DPN-OLTP-OLAP-001 | Olap客户端查询数据源失败。 |
DPN-OLTP-OLAP-002 | Olap客户端运行失败。 |
DPN.Oltp.Olap.SessionError | Olap的Session错误。 |
DPN.Oltp.Olap.SessionNotFound | Olap的Session不存在。 |
常见问题
问题:调用API报404 回答:
如果绑定了独立域名,请检查是HTTP协议还是HTTPS协议。
检查调用的API创建的类型是LIST还是GET,因为LIST/GET会作为URL的一部分。
检查API是否发布到对应的环境。
public static ApiClient getClient() { if (apiClient == null) { synchronized (ClientDemo.class) { if (apiClient == null) { ... params.setStage("RELEASE"); params.setEnv("PROD"); apiClient = new ApiClient(params); return apiClient; } } }
问题:调用API报400 回答:
请检查
x-ca-timestamp
是否在15分钟的有效期内,x-ca-nonce
在15分钟内是否被重复使用,建议每次请求API,x-ca-timestamp
取当前时间,x-ca-nonce
新生成可以用UUID生成,作为唯一标识,没有格式要求。检查使用AppKey、AppSecret是否前后有空格。
检查调用的API是否已授权,并且授权的APPSecret和AppKey是否和下面参数
private static final String APP_KEY
和private static final String APP_SECRET
一致,不一致情况下出现400错误。注意检查客户端的签名值是否多加了空格,传给服务端的没有加(Invalid Signature),检查
stringToSign
中的值是否有空格,如客户端签名Content-Type:application/octet-stream; charset=utf-8
有空格,但是传给服务端的没有空格Content-Type:application/octet-stream;charset=utf-8
,就会报错Invalid Signature
。
问题:调用API报403
回答:可能的原因:①调用协议与实际配置不匹配,②AppKey和AppSecret不正确。
检查API配置的调用协议是HTTP还是HTTPS,在代码中设置为对应的参数。
public static ApiClient getClient() { if (apiClient == null) { synchronized (ClientDemo.class) { if (apiClient == null) { ... //默认为http协议, 可设置https协议(os网关不支持https!!,非os网关可以支持https,具体决定于所调用的API) // 这里 params.setScheme(Scheme.HTTP); // 或 params.setScheme(Scheme.HTTPS); ... } } } return apiClient; }
检查AppKey和AppSecret是否正确。
问题:调用API报错:return fields missing in param
回答:在packRequestParamListSync或packRequestParamGetSync(根据API的GET或LIST类型)方法中,按照下方脚本设置参数。
ArrayList<String> returnFiles = Lists.newArrayList("api的返回字段1","api的返回字段2",..."api的返回字段n");
queryParamRequest.setReturnFields(returnFiles);
问题:如何使用operator为IN
的参数
回答:在SDK调用时,IN
类型的参数需要使用LIST传递参数值,例如:
假设参数名为p1,参数类型为String或Date,参数值为a、b、c,则应按下面方式设置参数:
HashMap<String, Object> condition = Maps.newHashMap();
condition.put("p1",Lists.newArrayList("a", "b", "c"));
如果是数值类型,参数值为1、2、3,则应按下面方式设置参数:
HashMap<String, Object> condition = Maps.newHashMap();
condition.put("p1",Lists.newArrayList(1,2,3));
问题:使用SDK分页获取数据时,数据总数正确,但存在重复数据
原因:API代码中未使用排序字段使每次的排序结果唯一,或数据库本身不支持排序,导致每次分页获取数据时的查询结果的排序不一致,导致重复获取数据或丢失数据。
回答:确保返回结果排序的稳定性。若有主键,可增加主键字段排序,如果没有主键,可使用多个字段组成联合主键排序,确保每次排序的结果是稳定的。