附录:API调用示例

API可使用SDK调用方式(包括Java SDKPython SDK)及白名单免密调用方式。其中仅使用私有网关的时候支持白名单方式。本篇API调用示例为调用模板,您可根据模板配置API的调用示例。

SDK调用

Java SDK简介

Dataphin数据服务Java SDK为您提供了快速调用数据服务API的基础SDK及示例调用代码。这里向您介绍如何使用Dataphin服务Java SDK。

Java SDK的代码文件层级结构如下:

重要

JAR包版本可能跟随SDK的升级而升级。

Java SDK/

  • demo/

    • ClientDemo.java提供了同步API的调用示例和方法。

    • AsyncClientDemo.java提供了异步API的调用示例和方法。

  • lib/

    • dataphin-sdk-core-java-v5.4.0.jarSDK的依赖包。

    • dataphin-sdk-core-java-v5.4.0-javadoc.jar上述依赖包的Javadoc。

    • dataphin-sdk-core-java-v5.4.0-jar-with-dependencies.jar上述依赖包的全依赖包。

  • ApiDocument_v5.4.0.mdAPI接口文档。

  • LICENSE许可证。

Java SDK获取方式如下:

  1. Dataphin首页的顶部菜单栏,选择服务 > 应用管理

  2. 在左侧导航栏单击调用说明

  3. 单击API调用说明页签,在页面右上方选择Java SDK下载,将下载SDKJar包添加至pom.xml中。

Java SDK调用同步API流程

重要
  • 在调用API之前,您首先需要初始化客户端。

  • API的响应时间较长,可使用异步调用,在整个等待应答期间,主线程不会被阻塞。

  • 您可以实例化QueryParamRequest对象,并且设置请求参数满足不同的查询需要,详情请参考调用实例中的packRequestParam方法。

  • API请求和返回结果信息请查看SDK中的APIDocument.md

  • 若在使用中遇到问题,请咨询Dataphin技术支持。

步骤一:环境准备

  1. Dataphin服务Java SDK适用于JDK 1.8及以上版本。

  2. 您需要准备一对授权密钥供SDK生成鉴权和签名信息,即AppKeyAppSecret。

    AppKeyAppSecret可在服务 > 应用管理 > 我的应用列表中获取。

    重要

    AppKeyAppSecretDataphin数据服务认证用户请求的密钥,这两个配置如果保存在客户端,请妥善加密。

  3. pom.xml中添加如下依赖,如果添加dataphin-sdk-core-java报错请手动添加该JAR文件,路径JAVA_SDK/lib/dataphin-sdk-core-java-v5.4.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.4.0</version>
    </dependency>

步骤二:引入Java SDKAPI接口调用类

  1. 服务 > API市场 > API列表中下载对应的API文档。

  2. 导入ClientDemo.java,修正ClientDemo.java类的importpackage。

    import java.util.*;
    import java.util.function.Consumer;
    
    import com.alibaba.cloudapi.sdk.constant.SdkConstant;
    import com.alibaba.cloudapi.sdk.enums.Scheme;
    import com.alibaba.cloudapi.sdk.model.ApiCallback;
    import com.alibaba.cloudapi.sdk.model.ApiRequest;
    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.client.sse.SseApiClient;
    import com.alibaba.dt.dataphin.schema.ManipulationParamRequest;
    import com.alibaba.dt.dataphin.schema.OrderBy;
    import com.alibaba.dt.dataphin.schema.QueryParamRequest;
    import com.alibaba.fastjson.JSON;
    
    /**
     * 同步API示例
     * <p>
     * 使用方式:
     *  先配置好 HOST/APP_KEY/APP_SECRET/API_ID,
     *  再按需设置 getClient() 中的变量以及 packQueryParamRequest() 中的参数值。
     * 注意:
     *  getClient() 中的参数可能会因不同的 API 而设置不同的值,可以将 getClient() 改造成带有入参,以适应不同 API 使用不同的参数。
     */
    public class ClientDemo {
    
        /**
         * 访问域名或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();
            // 流式调用GET类型API
            fluxGet();
            // 分页查询的api,同时获取查询总数
            syncListWithTotalNum();
    
            // 同步调用Create类型API
            syncCreate();
            // 同步调用Update类型API
            syncUpdate();
            // 同步调用Delete类型API
            syncDelete();
        }
    
        private static void syncListWithTotalNum() {
            ApiClient client = getClient();
    
            // 需要按需修改里面的返回字段、查询条件等
            QueryParamRequest queryParamRequest = packRequestParamWithReturnNum();
    
            ApiResponse response = client.listSync(API_ID, queryParamRequest);
    
            String resultStr = getResultString(response);
    
            // contain totalNum in ResultBody
            System.out.println(resultStr);
        }
    
        /**
         * 同步调用GET类型API
         */
        public static void syncGet() {
            // 获取 ApiClient 对象
            ApiClient client = getClient();
    
            // 需要按需修改里面的返回字段、查询条件等
            QueryParamRequest queryParamRequest = packRequestParam();
    
            ApiResponse response = client.getSync(API_ID, queryParamRequest);
    
            System.out.println(getResultString(response));
        }
    
        /**
         * 同步调用LIST类型API
         */
        public static void syncList() {
            // 获取 ApiClient 对象
            ApiClient client = getClient();
    
            // 需要按需修改里面的返回字段、查询条件等
            QueryParamRequest queryParamRequest = packRequestParam();
    
            ApiResponse response = client.listSync(API_ID, queryParamRequest);
    
            System.out.println(getResultString(response));
        }
    
        /**
         * 同步调用Create类型API
         */
        public static void syncCreate() {
            // 获取 ApiClient 对象
            ApiClient client = getClient();
    
            // 按需修改入参信息
            ManipulationParamRequest manipulationParamRequest = packDmlRequestParam();
    
            ApiResponse response = client.createSync(API_ID, manipulationParamRequest);
    
            System.out.println(getResultString(response));
        }
    
        /**
         * 同步调用Update类型API
         */
        public static void syncUpdate() {
            // 获取 ApiClient 对象
            ApiClient client = getClient();
    
            // 按需修改入参信息
            ManipulationParamRequest manipulationParamRequest = packDmlRequestParam();
    
            ApiResponse response = client.updateSync(API_ID, manipulationParamRequest);
    
            System.out.println(getResultString(response));
        }
    
        /**
         * 同步调用Delete类型API
         */
        public static void syncDelete() {
            // 获取 ApiClient 对象
            ApiClient client = getClient();
    
            // 按需修改入参信息
            ManipulationParamRequest manipulationParamRequest = packDmlRequestParam();
    
            ApiResponse response = client.deleteSync(API_ID, manipulationParamRequest);
    
            System.out.println(getResultString(response));
        }
    
        /**
         * 异步调用GET类型API
         * 需要在回调方法中处理响应结果
         */
        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线程提前结束 ---");
        }
    
        /**
         * 异步调用LIST类型API
         * 需要在回调方法中处理响应结果
         */
        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线程提前结束 ---");
        }
    
        /**
         * 获取 ApiClient 对象
         */
        public static ApiClient getClient() {
            ApiClientBuilderParams params = new ApiClientBuilderParams();
            // 应用appKey
            params.setAppKey(APP_KEY);
            // 应用appSecret
            params.setAppSecret(APP_SECRET);
            // 访问域名或ip
            params.setHost(HOST);
            // 默认为http协议, 可根据API设置https协议
            // 注意:Dataphin内置网关不支持https,阿里云网关支持https
            params.setScheme(Scheme.HTTP);
            // 访问API的数据环境,生产环境:RELEASE,开发环境:PRE
            params.setStage("RELEASE");
            // 如果使用二级域名或未指定环境的独立域名,需要设置env
            // 有 PROD 和 PRE 两种值(如果是basic模式,传PROD; 如果是Dev-Prod模式,PROD表示查生产环境数据库,PRE表示查开发环境数据库)
            // 如果已经指定了访问环境的独立域名,则env参数不会起作用
            params.setEnv("PROD");
    
            ApiClient apiClient = new ApiClient(params);
            // 设置impala数据库类型的超时时间以及轮询间隔(可选,默认超时时间300s,轮询间隔800毫秒)
            // 参数只对impala有作用,调用非impalaAPI也要设置,保持默认即可
            apiClient.setImpalaTimeoutAndInterval(300, 800);
            return apiClient;
        }
    
        public static SseApiClient getSseClient() {
            ApiClientBuilderParams params = new ApiClientBuilderParams();
            // 应用appKey
            params.setAppKey(APP_KEY);
            // 应用appSecret
            params.setAppSecret(APP_SECRET);
            // 访问域名或ip
            params.setHost(HOST);
            // 默认为http协议, 可根据API设置https协议
            // 注意:Dataphin内置网关不支持https,阿里云网关支持https
            params.setScheme(Scheme.HTTP);
            // 访问API的数据环境,生产环境:RELEASE,开发环境:PRE
            params.setStage("RELEASE");
            // 如果使用二级域名或未指定环境的独立域名,需要设置env
            // 有 PROD 和 PRE 两种值(如果是basic模式,传PROD; 如果是Dev-Prod模式,PROD表示查生产环境数据库,PRE表示查开发环境数据库)
            // 如果已经指定了访问环境的独立域名,则env参数不会起作用
            params.setEnv("PROD");
            return new SseApiClient(params);
    
        }
    
        /**
         * 调用api包含consumer
         */
        public static void fluxGet() {
            Consumer<ApiResponse> consumer = r -> System.out.println(new String(r.getBody()));
            SseApiClient sseApiClient = getSseClient();
            // 对于短周期应用, 对于完成后可以将client的线程池关闭,释放资源
            sseApiClient.getFlux(API_ID, packRequestParam())
                    // 对于临时运行,完成式需要关闭连接释放资源
                    .doOnComplete(sseApiClient::shutdown)
                    .subscribe(consumer);
        }
    
        private static QueryParamRequest packRequestParamWithReturnNum() {
            QueryParamRequest queryParamRequest = packRequestParam();
            queryParamRequest.setReturnTotalNum(true);
            return queryParamRequest;
        }
    
        /**
         * 包装请求对象
         */
        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为请求字段名,1id对应的值,可以设置多个查询参数
             * 注意:如果是 IN 类型的参数,使用 List 包装参数值
             */
            Map<String, Object> conditions = new HashMap<>();
            conditions.put("id", 1);
            conditions.put("age", Arrays.asList(10, 20, 30));
            queryParamRequest.setConditions(conditions);
    
            /*
             * 返回参数列表,不能为空
             * 例如指定返回idname
             * 注意:返回参数如果不存在或没权限会报错
             */
            queryParamRequest.setReturnFields(Arrays.asList("id", "name"));
    
            /*
             * 排序字段,非必填
             * 注意oraclesqlServer使用分页需要同时使用排序
             * 指定参数升序或者降序,可设置多个字段进行升序或者降序
             * 例如返回结果按id进行升序
             */
            List<OrderBy> orderList = new ArrayList<>();
            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版本号,非必填,仅开发环境API支持设置
             */
            // queryParamRequest.setApiVersion("V1");
    
            /********* API相关业务参数设置 end *********/
    
    
            /********* 功能参数设置 begin *********/
    
            /*
             * 是否使用模型缓存
             * 开启会减少同一个服务单元API相同出入参时的解析频次,提高查询效率
             */
            queryParamRequest.setUseModelCache(false);
    
            /*
             * 是否使用结果缓存
             * 开启则会缓存同一个API相同条件、相同返回字段的查询结果
             * 适用于数据不变化的查询,减少相同SQL的查询频次,提高查询效率
             * 缓存时长默认30分钟,3.5.6 版本后,在API开发页面可设置缓存时长
             * 注意:如果API未开启结果缓存,该参数无效
             */
            queryParamRequest.setUseResultCache(false);
    
            /*
             * 是否保持字段的大小写格式
             * 如果对大小写敏感,建议设置为true
             * 为false时,直连API返回结果的字段名默认为大写字母
             */
            queryParamRequest.setKeepColumnCase(true);
    
            /********* 功能参数设置 end *********/
    
            return queryParamRequest;
        }
    
        /**
         * 包装DML请求对象
         */
        private static ManipulationParamRequest packDmlRequestParam() {
            ManipulationParamRequest manipulationParamRequest = new ManipulationParamRequest();
    
            /*
             * 请求参数列表,非必填的参数可不传,必填参数必须传,否则会报错
             * 其中key为对应的字段名,value为字段对应的值
             * 例如这里的id为请求字段名,1id对应的值,可以设置多个参数
             * 注意:如果是 IN 类型的参数,使用 List 包装参数值
             */
            Map<String, Object> conditions = new HashMap<>();
            conditions.put("id", 1);
            conditions.put("age", Arrays.asList(10, 20, 30));
            manipulationParamRequest.setConditions(conditions);
    
            /*
             * 如果API的数据量是批量时,需要将入参放入batchConditions中
             */
            List<Map<String, Object>> batchConditions = new ArrayList<>();
            batchConditions.add(conditions);
            manipulationParamRequest.setBatchConditions(batchConditions);
    
            /*
             * API版本号,非必填,仅开发环境API支持设置
             */
            // manipulationParamRequest.setApiVersion("V1");
    
            return manipulationParamRequest;
        }
    
        /**
         * 获取结果字符串
         */
        private static String getResultString(ApiResponse response) {
            /*
             * step 1: 获取HttpResponse中头部的详细信息方式
             *         response.getHeaders().get(key)
             *         说明:key取值有"date\server\transfer-encoding\keep-alive\vary\connection\content-type\x-ca-request-id\x-ca-error-message\x-ca-error-code"
             *              如果API调用失败,Headers会有x-ca-error-message(错误信息描述)和x-ca-error-code(网关错误状态码),如果成功则不会存在该信息,
             *              但是x-ca-request-id(每次请求的唯一标识)始终会有。
             *         推荐:如果返回code不是200,可打印出x-ca-error-message\x-ca-error-code以便排查问题
             *         强制:使用中需要打印出x-ca-request-id,便于查看日志
             *
             * step 2:下面已经打印出response的详细信息,实际开发中可以根据step1中描述,选择输出相关信息
             */
            System.out.println("返回结果详细信息: "+ SdkConstant.CLOUDAPI_LF + JSON.toJSONString(response) + SdkConstant.CLOUDAPI_LF);
    
            StringBuilder result = new StringBuilder();
            result.append("Response from backend server").append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF);
            result.append("ResultCode:").append(SdkConstant.CLOUDAPI_LF).append(response.getCode()).append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF);
            result.append("RequestId:").append(SdkConstant.CLOUDAPI_LF).append(response.getHeaders().get("x-ca-request-id")).append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF);
            if (200 != response.getCode()) {
                result.append("ErrorCode:").append(SdkConstant.CLOUDAPI_LF).append(response.getHeaders().get("x-ca-error-code")).append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF);
                result.append("ErrorMessage:").append(SdkConstant.CLOUDAPI_LF).append(response.getHeaders().get("x-ca-error-message")).append(SdkConstant.CLOUDAPI_LF).append(SdkConstant.CLOUDAPI_LF);
            }
            result.append("ResultBody:").append(SdkConstant.CLOUDAPI_LF).append(new String(response.getBody(), SdkConstant.CLOUDAPI_ENCODING));
    
            /*
             * 查看结果 如果状态码不是200,可查看x-ca-error-message报错信息排查问题
             * 建议用户保存x-ca-request-id参数,如有异常请提供该参数以便我们排查问题
             */
            return result.toString();
        }
    
    }
    

步骤三:初始化通信通道类

要调用API,首先要初始化客户端。您可以参考ClientDemo.javagetClient方法,使用对应的ApiClientBuilderParams类来进行初始化。其中,您需要将Host、APP_KeyAPP_Secret三个变量进行替换。

步骤四:API接口说明

  • API接口类型

    • API接口类型分为查询类型(LIST、GET)和操作类型(CREATE、UPDATE、DELETE)。

    • LIST支持分页查询而GET不支持分页查询,请参考ClientDemo.javapackRequestParam方法,设置QueryParamRequest里的参数。

    • 操作类型API请参考ClientDemo.java中的packDmlRequestParam方法,设置ManipulationParamRequest里的参数。

  • 调用API接口

    • SDK中的LISTGET方法为Dataphin数据服务的通用方法,SDK中提供同步和异步的调用方法。在调用API之前,您需要根据您在Dataphin数据服务中定义的API填入相关的请求参数。

    • 调试用例中conditions为查询类API的业务请求参数,returnFieldsAPI的返回参数,具体参数请参考服务 > 应用管理 > 已授权API服务页面,单击目标API操作列下调试,进入调试页面。

    • 操作类API的业务参数需要根据API配置的数据量进行区分,单条的入参通过conditions进行传递,批量的入参需要通过batchConditions进行传递。

    • 请求参数中的API_ID,请参考服务 > 应用管理 > 已授权API服务页面API列下的API_ID。

Java SDK调用异步API流程

重要
  • 在调用API之前,您首先需要初始化客户端。

  • API的响应时间较长,可使用异步调用,在整个等待应答期间,主线程不会被阻塞。

  • 您可以实例化QueryParamRequest对象,并且设置请求参数满足不同的查询需要,详情请参考调用实例中的packRequestParam方法。

  • API请求和返回结果信息请查看SDK中的APIDocument.md

  • 若在使用中遇到问题,请咨询Dataphin技术支持。

步骤一:环境准备

  1. Dataphin服务Java SDK适用于JDK 1.8及以上版本。

  2. 您需要准备一对授权密钥供SDK生成鉴权和签名信息,即AppKeyAppSecret。

    AppKeyAppSecret可在服务 > 应用管理 > 我的应用列表中获取。

    重要

    AppKeyAppSecretDataphin服务认证用户请求的密钥,这两个配置如果保存在客户端,请妥善加密。

  3. pom.xml中添加如下依赖,如果添加dataphin-sdk-core-java报错请手动添加该JAR文件,路径JAVA_SDK/lib/dataphin-sdk-core-java-v5.4.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.4.0</version>
    </dependency>

步骤二:引入Java SDKAPI接口调用类

  1. 服务 > API市场 > API列表中下载对应的API文档。

  2. 导入AsyncClientDemo.java,修正AsyncClientDemo.java类的importpackage。

    package com.alibaba.dt.dataphin;
    
    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 java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.List;
    
    /**
     * 异步API示例
     * <p>
     * 使用方式:
     *  先配置好 HOST/APP_KEY/APP_SECRET/API_ID,
     *  再按需设置 getClient() 中的变量以及 packQueryParamRequest() 中的参数值
     * 注意:
     *  getClient() 中的参数可能会因不同的 api 而设置不同的值,可以将 getClient() 改造成带有入参,以适应不同 api 使用不同的参数。
     */
    public class AsyncClientDemo {
    
        /**
         * 访问域名或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();
    
            try {
                AsyncQueryResults asyncQueryResults = asyncApiClient.listAsyncWaitFinish(API_ID, queryParamRequest);
    
                System.out.println(JSONObject.toJSONString(asyncQueryResults));
            } catch (Throwable e) {
                e.printStackTrace();
            }
    
            // 关闭客户端,回收资源
            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();
        }
    
        /**
         * 获取 AsyncApiClient 对象
         */
        public static AsyncApiClient getClient() {
            ApiClientBuilderParams params = new ApiClientBuilderParams();
            // 应用appKey
            params.setAppKey(APP_KEY);
            // 应用appSecret
            params.setAppSecret(APP_SECRET);
            // 访问域名或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为请求字段名,1id对应的值,可以设置多个查询参数
             * 注意:如果是 IN 类型的参数,使用 List 包装参数值,例如这里的age
             */
            HashMap<String, Object> conditions = new HashMap<>();
            conditions.put("id", 1);
            conditions.put("age", Arrays.asList(10,20,30));
            queryParamRequest.setConditions(conditions);
    
            /*
             * 返回参数列表,必填
             * 例如指定返回idname
             * 注意:返回参数如果不存在或没权限会报错
             */
            queryParamRequest.setReturnFields(Arrays.asList("id", "name"));
    
            /*
             * 排序字段,非必填
             * 注意oraclesqlServer使用分页需要同时使用排序
             * 指定参数升序或者降序,可设置多个字段进行升序或者降序
             * 例如返回结果按id进行升序
             */
            List<OrderBy> orderList = new ArrayList<>();
            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,首先要初始化客户端。您可以参考AsyncClientDemo.javagetClient方法,使用对应的ApiClientBuilderParams类来进行初始化。其中,您需要将Host、APP_KeyAPP_Secret三个变量进行替换。

步骤四:API接口说明

  • API接口类型

    API接口类型分为LISTGET,LIST支持分页查询而GET不支持,请参考AsyncClientDemo.java中的packRequestParam方法,设置QueryParamRequest里的参数。

  • 调用API接口

    • SDK中的LISTGET方法为Dataphin数据服务的通用方法,SDK中同时提供同步和异步的调用方法。在调用API之前,您需要根据您在Dataphin数据服务定义的API填写相关的请求参数。

    • 调试用例中conditions为业务请求参数,returnFieldsAPI的返回参数,具体参数请参考服务 > 应用管理 > 已授权API服务页面,单击目标API操作列下调试,进入调试页面。

    • 请求参数中的API_ID,请参考服务 > 应用管理 > 已授权API服务页面API列下的API_ID。

Python SDK调用流程

步骤一:环境准备

  1. Python SDK适用于Python3.9及以上版本。

    Python SDK获取方式如下:

    1. Dataphin首页的顶部菜单栏,选择服务 > 应用管理

    2. 在左侧导航栏单击调用说明

    3. 单击API调用示例页签,单击页面右上方的python调用示例下载按钮,获取Python SDK core包。

  2. 准备一对授权密钥供SDK生成鉴权和签名信息,即AppKeyAppSecret。

    重要

    AppKeyAppSecretDataphin服务认证用户请求的密钥,这两个配置如果保存在客户端,请妥善加密。

  3. 准备一个JSON文件,格式如下:

    {
      "host": "API网关域名",
      "port": 80,
      "impalaConfig": {
        "pollingTimeout": 300,
        "pollingInterval": 800
      },
      "applicationConfig": {
        "appKey": "敏感数据自行填充",
        "appSecret": "敏感数据自行填充"
      },
      "apiConfig": {
        "apiNo": 10008,
        "scheme": "HTTP",
        "stage": "RELEASE",
        "env": "PROD",
        "method": "LIST", // GET、LIST、CREATE、UPDATE、DELETE,区分大小写
        "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,非必填,使用代理模式时需要配置此参数
        },
        "manipulationParamRequest": {
          "conditions": {"id": "1"}, // 数据量为“单条”的API的请求参数,非必填参数可不传,必填参数必须传
          "batchConditions": [ // 数据量为“批量”的API的请求参数,非必填参数可不传,必填参数必须传
            {"id": "1"},
            {"id": "2"}
          ]
        }
      }
    }

步骤二:部署Python SDK

  1. 安装Python开发工具PyCharm。

  2. 打开Python项目。

  3. Demo类的启动参数上配置JSON文件路径。

  4. 具体调用请参照demo.py。

步骤三:调用API

  1. JSON文件中配置调用参数信息。

  2. Python SDK通过读取JSON文件来组装API调用的基础参数。

  3. 调用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', ''))
    # This is a JSON file for reading context. If you don't need a JSON file, just fill in the corresponding values directly
    
    # Gateway call address
    host = json_obj["host"]
    # Gateway call port
    port = json_obj["port"]
    # No configuration is required. Only valid for Impala type APIs, polling timeout
    pollingTimeout = json_obj["impalaConfig"]["pollingTimeout"]
    # No configuration is required. Only valid for Impala type APIs, polling interval
    pollingInterval = json_obj["impalaConfig"]["pollingInterval"]
    # Which app do you use to call this API for app information
    appKey = json_obj["applicationConfig"]["appKey"]
    appSecret = json_obj["applicationConfig"]["appSecret"]
    # Information about API
    apiId = json_obj["apiConfig"]["apiNo"]
    # How to call the API? The value is: HTTP or HTTPS. Note that the private gateway only supports HTTP [case sensitive]
    scheme = json_obj["apiConfig"]["scheme"]
    # Just write 'RELEASE'
    stage = json_obj["apiConfig"]["stage"]
    # There are two values: PROD and PRE (if in basic mode, PROD is passed to death; if in Dev Pro mode, PROD represents checking the production library, and PRE represents checking the development library [case sensitive])
    env = json_obj["apiConfig"]["env"]
    # Query API Request parameters
    queryParam = json_obj["apiConfig"]["queryParamRequest"]
    # Manipulation API Request parameters
    manipulationParam = json_obj["apiConfig"]["manipulationParamRequest"]
    # Is the API GET/LIST/CREATE/UPDATE/DELETE? Distinguish between uppercase and lowercase letters
    method = json_obj["apiConfig"]["method"]
    
    if (host == None or host == ""):
        raise Exception("host is missing")
    
    if (appKey == None or appKey == ""):
        raise Exception("appKey is missing")
    
    if (appSecret == None or appSecret == ""):
        raise Exception("appSecret is missing")
    
    if (method == None or method == ""):
        raise Exception("method is missing")
    
    if (apiId == None or apiId == ""):
        raise Exception("apiNo is missing")
    
    # 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)
    
    # sync query API request
    resp = apiClient.callApi(queryParam)
    print(resp)
    
    # async query API request
    asyncResp = apiClient.asyncCallApi(queryParam)
    print(asyncResp)
    
    # flux API request
    sseClient = dataapi.SseApiClient(myConfig)
    fluxResp = sseClient.fluxCallApi(queryParam)
    for item in fluxResp:
        print(item)
    
    # sync manipulation API request
    resp = apiClient.callApi(manipulationParam)
    print(resp)

白名单调用方式(仅私有化部署时支持)

通过配置白名单免密方式访问API的安全策略,可简化API调用流程。IP白名单策略为应用级别策略,目前仅私有云支持此方式调用。

开发流程

步骤一:后台配置

您需要在数据服务中创建API、应用、应用白名单以及将应用和API进行绑定,才能通过白名单方式访问API。

  • 创建API:您可在服务 > API开发 > API服务API页面,选择对应的方式创建API,详情请参见创建API

  • 创建应用及应用白名单:应用可用于调用生产环境的API,并可为API设置白名单,如何创建应用及白名单,请参见新建及管理我的应用

  • 应用和API绑定:需申请该API的所属应用权限才能使用该API,如何申请,请参见管理API权限

步骤二:发起请求

  1. 请求类型:POST

    只支持POST提交的请求,BODY一律使用JSON字符串,并且Content-Type设置为application/octet-stream; charset=utf-8

  2. 设置公共入参

    参数名

    位置

    是否必填

    示例

    说明

    accept

    Header

    application/json; charset=utf-8

    响应格式。

    host

    Header

    gateway.aliyun.com

    API网关域名。

    x-ca-key

    Header

    敏感数据自行填充

    appkey,调用API的身份标识。

    x-ca-stage

    Header

    RELEASE

    环境标识。

    • RELEASE访问生产环境。

    • PRE访问开发环境。

    Content-Type

    Header

    application/octet-stream; charset=utf-8

    请求格式。

    whitelist-flag

    Header

    1

    白名单标识(非空),固定传1。

  3. 请求格式

    • URL:POST [host]/method/apiId?appKey=应用的AppKey&env=PROD

      • host:API网关域名(可在服务 > 服务管理 > 网络配置页面获取)。

      • method:API的操作类型,GET/LIST/CREATE/UPDATE/DELETE(可在服务 > 应用管理> 已授权API服务 > 调试页面获取)。

      • apiId:API的唯一标识(可在服务 > 应用管理> 已授权API服务 > 调试页面获取)。

      • appKey:该API绑定的应用的唯一标识(可在服务 > 应用管理 > 我的应用页面获取)

      • env:环境标识,PROD表示访问生产环境上的API,PRE表示访问开发环境的API。

      请求URL示例:gateway.aliyun.com/list/12345?appKey=xxx&env=PROD

  4. 使用PostMan调用示例

    1. 步骤一:请求地址

      请求POST地址[host]/method/apiId?appKey=应用的AppKey&env=PROD

    2. 步骤二:填入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
    3. 步骤三:填入body

      说明

      Content-Type使用application/octet-stream; charset=utf-8

      body示例:

      {
        "conditions": {"id": "1"}, // 请求参数列表,根据参数决定,非必填参数可不传,必填参数必须传
        "batchConditions": [{"id": "1"}], // 数据量为“批量”的操作类API的请求参数,非必填参数可不传,必填参数必须传
        "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

APPSecret错误

检查传入的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

OlapSession错误。

DPN.Oltp.Olap.SessionNotFound

OlapSession不存在。

常见问题

问题1:调用API404 回答

  • 如果绑定了独立域名,请检查是HTTP协议还是HTTPS协议。

  • 检查调用的API的操作类型是否和API的一致,因为操作类型会作为URL的一部分,确保根据操作类型调用正确的方法。

  • 检查API是否发布到对应的环境。

问题2:调用API400 回答

  • 请检查x-ca-timestamp是否在15分钟的有效期内,x-ca-nonce15分钟内是否被重复使用,建议每次请求API,x-ca-timestamp取当前时间,x-ca-nonce新生成可以用UUID生成,作为唯一标识,没有格式要求。

  • 检查使用AppKey、AppSecret是否前后有空格。

  • 检查调用的API是否已授权,并且授权的APPAppKey、Secret和参数APP_KEY、APP_SECRET是否一致。

  • 注意检查客户端的签名值是否多加了空格,传给服务端的没有加(Invalid Signature),检查stringToSign中的值是否有空格,如客户端签名Content-Type:application/octet-stream; charset=utf-8有空格,但是传给服务端的没有空格Content-Type:application/octet-stream;charset=utf-8,就会报错Invalid Signature

问题3:调用API403

回答

  • 检查API配置的调用协议是HTTP还是HTTPS,在代码中设置为对应的参数。

  • 检查AppKeyAppSecret是否正确。

  • 检查调用的API的操作类型是否和API的一致,因为操作类型会作为URL的一部分,确保根据操作类型调用正确的方法。

问题4:调用API报错:return fields missing in param

回答packRequestParam方法中,按下面方式设置参数:

List<String> returnFields = Lists.newArrayList("api的返回字段1","api的返回字段2",..."api的返回字段n");
queryParamRequest.setReturnFields(returnFields);

问题5:如何使用operatorIN的参数

回答:在SDK调用时,IN类型的参数需要使用LIST传递参数值,例如:

  • 假设参数名为p1,参数类型为StringDate,参数值为a、b、c,则应按下面方式设置参数:

Map<String, Object> conditions = Maps.newHashMap();
conditions.put("p1",Lists.newArrayList("a", "b", "c"));
  • 如果是数值类型,参数值为1、2、3,则应按下面方式设置参数:

Map<String, Object> conditions = Maps.newHashMap();
conditions.put("p1",Lists.newArrayList(1,2,3));

问题6:使用SDK分页获取数据时,数据总数正确,但存在重复数据

原因API代码中未使用排序字段使每次的排序结果唯一,或数据库本身不支持排序,导致每次分页获取数据时的查询结果的排序不一致,导致重复获取数据或丢失数据

回答确保返回结果排序的稳定性。若有主键,可增加主键字段排序,如果没有主键,使用多个字段组成联合主键排序,确保每次排序的结果是稳定的

问题7使用SDK分页获取数据时,如何设置参数返回总数

回答packRequestParam方法中,按下面方式设置参数:

// 是否返回总数(用于支持分页的api查询)
queryParamRequest.setReturnTotalNum(false);