跳到主要内容

API使用说明

概述

数据消费人员可以通过 API 接口访问 HEXADB 开放的数据。消费人员用户需要先使用自己的密钥(AKSK)获取具有时效性的数据访问令牌(token),之后可以使用该令牌(token)多次访问数据 API 接口,获取已授权的数据。

基本步骤如下:

  1. 获取密钥:用户在平台中可以创建管理自己的 AKSK,可以进行下载操作获取 AKSK 具体信息;
  2. 生成密文:用户使用 AKSK 按规则自行生成密文;
  3. 获取令牌:使用上一步骤中生成的密文访问数据登录接口,通过验证后获得数据访问令牌;
  4. 访问数据:使用上一步骤中获取的数据访问令牌,可以在有效期内(生效时长可在密文中指定,令牌有效期从令牌的获取时间开始计算,具体内容可参考生成密文获取令牌部分)多次访问数据 API 接口,获取数据。

第一步:获取密钥(AKSK)

用户在平台登录后,进入 “个人中心” 下的 "AKSK管理" 页面,可以下载自己的 AKSK。
用户在这里可以创建管理多个 AKSK,每个 AKSK 的数据访问效力是等同的,都可以用来访问用户已被授权的所有数据。用户可以按实际需要使用,例如用不同的 AKSK 区分用途,用新 AKSK 逐步替换旧 AKSK。
API参考
用户下载 AKSK 可获取到 AKSK 的密钥 ID(Access Key) 和私钥(Private Key),另外附带一个 7200 秒有效时长的密文,用户可以选择直接使用,也可以执行第二步从 AKSK 生成自定义的密文。如下所示:

注意
Access Key:
0e55fe87-b411-4a35-94df-22a0f5b4881e

Private Key:
MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQCyImK4+7t...

7200s Secret:
8e711a97-d1d1-4454-b04b-833579711115@7200#aS74Nzrzj40xSn4osIoorx4eE6LYh...

第二步:生成密文

用户需要基于 AKSK 生成密文,来获得真正能用来访问数据的令牌。这一过程可以支持区分 AKSK 的管理者和使用者,即如果需要,AKSK 的管理者可以将密钥ID(Access Key)和具有时效性的密文分发给真正的使用方,而不是直接把私钥(Private Key)交给他人使用。
密文的生成使用一个随机的 UUID 和有效时间(整数,单位秒),用符号 @ 拼接后的内容是明文,对这个明文使用 AKSK 的私钥(Private Key)生成签名,再将明文和签名用 # 拼接在一起就得到了密文。

示例代码
/**
* 通过 AK/SK 生成密文
* @param effectiveTime 生效时长,单位秒,例如 3600 代表 1 小时,最长不超过一天
* @param privateKeyHex 私钥(AK/SK Private Key)
*/
public static String sign(int effectiveTime, String privateKeyHex) {
try {
// 拼接明文
String rawContent = String.format("%s@%d", UUID.randomUUID(), effectiveTime);

// 获得私钥对象
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(
Base64.getDecoder().decode(privateKeyHex.getBytes(StandardCharsets.UTF_8)));
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpec);

// 生成签名
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(rawContent.getBytes(StandardCharsets.UTF_8));
String signatureHex = new String(Base64.getEncoder().encode(signature.sign()), StandardCharsets.UTF_8);

// 拼接返回结果
return rawContent + "#" + signatureHex;
} catch(Exception e) {
// 生成密文错误处理
return null;
}
}

第三步:获取令牌

有了密文,就可以通过数据登录接口获取真正用来访问数据的令牌(token)了。数据登录接口在校验密文通过后就会颁发数据访问令牌。一个密文可以重复多次获取令牌,每个获取到的新令牌都具有密文中指定的持续有效时长,从令牌的获取时间开始计算。
接口说明

  • 请求地址: http://域名/open-api/asset/access-key/login
  • 请求方式: POST
  • 请求参数:
    • Header 无
    • Body
      • accessKey 字符串,必填项,AKSK 密钥 ID(即 Access Key)
      • secret 字符串,必填项,通过上面第二步得到的密文
  • 返回值
    • HTTP 状态码
      • 200 表示令牌创建成功
      • 500 表示创建失败,可能是用户失效、AKSK 失效、签名验证失败等
    • 数据
      • code 整数类型,200 表示成功,500 开头的代码表示失败
      • message 字符串,成功时为 "success",失败时为具体失败信息
      • data 字符串,成功时内容就是数据访问令牌,失败时为空(不返回)
      • success 布尔值,true 表示成功,false 表示失败

调用示例

Curl调用示例
curl -X POST "http://域名/open-api/asset/access-key/login" -H "Content-Type: application/json" --data-raw "{ \"accessKey\": \"6fa42a46-493...\", \"secret\": \"58c99019-b0d2-4c...\" }"
正常调用应答示例:
{"code":200,"message":"success","data":"eyJ0eXAiOi...","success":true}

第四步:访问数据

1. 数据表、主数据、视图访问

使用数据访问令牌(token)可以通过数据 API 接口获取数据。用户提供期望执行的只读查询 SQL,数据 API 接口会校验用户是否已经具有该查询涉及数据的授权,校验通过后会按用户指定的格式返回查询结果数据。
接口说明

  • 请求地址: http://域名/open-api/asset/access-key/sql/query
  • 请求方式: POST
  • 请求参数:
    • Header
      • x-token 字符串,必填项,通过上面第三步得到的数据访问令牌
    • Body
      • sql 字符串,必填项,SQL 查询语句
      • format 字符串,非必填项,要求返回的结果格式,可用的取值和含义如下:
        • CSV_WITH_HEADER 格式是 CSV,首行是列名,默认值
        • CSV 格式是 CSV,没有列名首行
        • JSON 作为完整的 JSON 对象数组返回,每行查询结果一个 JSON 对象
        • JSON_ROWS 每行查询结果返回一行,一行是一个 JSON 对象
      • timeout 查询超时时间,必填项,单位秒,为 0 时表示不限时间
      • limit 结果数量限制,非必填项,最大限制为 10000 行

调用示例

Curl调用示例
curl -L -X POST "http://域名/open-api/asset/access-key/sql/query" -H "Content-Type: application/json" -H "x-token: eyJ0eXAiOiJKV1QiLC..." -d "{ \"sql\": \"select name, grade from stg.student\", \"timeout\": 15, \"limit\": 100, \"format\": \"CSV_WITH_HEADER\" }"
正常调用应答示例:

CSV_WITH_HEADER 首行是列名的 CSV

name,grade  
Tom,2
Jerry,3

CSV 纯数据 CSV

Tom,2  
Jerry,3

JSON 完整 JSON 数组

[{"name":"Tom","grade":"2"},{"name":"Jerry","grade":"3"}]  

JSON_ROWS 每行一个JSON

{"name":"Tom","grade":"2"}  
{"name":"Jerry","grade":"3"}

注意事项

数据权限检查

数据 API 接口会校验用户是否具有执行该 SQL 需要的数据授权。会检查 SQL 中涉及的所有数据表和字段,包括结果集中的字段、各个子查询的字段以及查询条件中关联的所有表和字段。

数据表需要指定模式

SQL 中引用的数仓数据表,都需要指定模式(Schema),别名不受影响。

结果集列限制

由于数据脱敏要求,对 SQL 返回结果集各列有严格的限制,只能直接引用数据表的列,或常量值,包括函数(例如 count、concat),二元运算符(例如 user_id > 0),以及 case 语句等都是不允许的。
所有的查询条件以及各个子查询的结果字段不受此限制。

SQL 子句、条件尽量简化

由于数据脱敏要求,请使用直接针对数据表列的查询和条件判断,列、数组的拆分、转换例如 UNNEST、LATERAL VIEW 等都是不允许的。

SQL Limit 生效

SQL 中的 limit、offset 是生效的,但是接口参数 limit 的限制优先生效。

流式数据返回

返回数据使用的是 HTTP 流式数据,需要持续读取应答流直至无数据可获取。

2. 派生指标访问

获取数据访问令牌(token)后可以通过数据 API 接口获取派生指标数据。用户提供期望执行的数据 API 接口会校验用户是否已经具有该查询涉及数据的授权,校验通过后会按用户指定的格式返回查询结果数据。
接口说明

  • 请求地址: http://域名/open-api/asset/resources/indicators/derive
  • 请求方式: POST
  • 请求参数:
    • Header
      • x-token 字符串,必填项,通过上面第三步得到的数据访问令牌
    • Body
      • key 字符串,必填项,数据访问指标,可在个人中心 > 审批管理 > 我已申请中点击审批通过的派生指标查看
      • format 字符串,非必填项,要求返回的结果格式,可用的取值和含义如下:
        • CSV_WITH_HEADER 格式是 CSV,首行是列名,默认值
        • CSV 格式是 CSV,没有列名首行
        • JSON 作为完整的 JSON 对象数组返回,每行查询结果一个 JSON 对象
        • JSON_ROWS 每行查询结果返回一行,一行是一个 JSON 对象
      • startTime 获取数据范围的起始时间,非必填项,参考格式 yyyy-MM-dd HH:mm:ss
      • endTime 获取数据范围的结束时间,非必填项,参考格式 yyyy-MM-dd HH:mm:ss

调用示例

Curl调用示例
curl -L -X POST "http://域名/open-api/asset/resources/indicators/derive" -H "Content-Type: application/json" -H "x-token: eyJ0eXAiOiJKV1QiLC..." -d "{ \"key\": \"17293990834...\", \"startTime\": \"2023-11-10 00:00:00\", \"endTime\": \"2023-12-01 00:00:00\", \"format\": \"CSV_WITH_HEADER\" }"
正常调用应答示例:

CSV_WITH_HEADER 首行是列名的 CSV

start_time,end_time,statistic_value,data_unit,statistic_date
2023-11-01 00:00:00,2023-11-30 23:59:59,11,,2023-12-01 00:05:08

CSV 纯数据 CSV

2023-11-01 00:00:00,2023-11-30 23:59:59,11,,2023-12-01 00:05:08  

JSON 完整 JSON 数组

[{"start_time": "2023-11-01 00:00:00", "end_time": "2023-11-30 23:59:59",
"statistic_value": "11","data_unit": "分","statistic_date": "2023-12-01 00:05:08"}]

JSON_ROWS 每行一个JSON

{"start_time":"2023-11-01 00:00:00","end_time":"2023-11-30 23:59:59",
"statistic_value":"11","data_unit":"分","statistic_date":"2023-12-01 00:05:08"}

3. 复合指标访问

获取数据访问令牌(token)后可以通过数据 API 接口获取复合指标数据。用户提供期望执行的数据 API 接口会校验用户是否已经具有该查询涉及数据的授权,校验通过后会按用户指定的格式返回查询结果数据。
接口说明

  • 请求地址: http://域名/open-api/asset/resources/indicators/compound
  • 请求方式: POST
  • 请求参数:
    • Header
      • x-token 字符串,必填项,通过上面第三步得到的数据访问令牌
    • Body
      • key 字符串,必填项,数据访问指标,可在个人中心 > 审批管理 > 我已申请中点击审批通过的复合指标查看
      • startTime 获取数据范围的起始时间,非必填项,参考格式 yyyy-MM-dd HH:mm:ss
      • endTime 获取数据范围的结束时间,非必填项,参考格式 yyyy-MM-dd HH:mm:ss
  • 返回数据:
    • code 返回代码,包括200,400,404,500
    • message 成功调用或具体的错误信息
    • data 对象数据,含复合指标值、计量单位

调用示例

Curl调用示例
curl -L -X POST "http://域名/open-api/asset/resources/indicators/compound" -H "Content-Type: application/json" -H "x-token: eyJ0eXAiOiJKV1QiLC..." -d "{ \"key\": \"17293990834...\", \"startTime\": \"2023-11-10 00:00:00\", \"endTime\": \"2023-12-01 00:00:00\" }"
正常调用应答示例:
{
"code": 200,
"message": "success",
"data": [
{
"startTime": "2023-11-01 00:00:00",
"endTime": "2023-11-30 23:59:59",
"statisticTime": "2023-12-01 00:05:08",
"indicatorValue": 1.1363636363636365,
"dateKey": "20231130",
"dataUnit": null
}
],
"success": true
}

4. 数据标签访问

获取数据访问令牌(token)后可以通过数据 API 接口获取数据标签。用户提供期望执行的数据 API 接口会校验用户是否已经具有该查询涉及数据的授权,校验通过后会按用户指定的格式返回查询结果数据。
接口说明

  • 请求地址: http://域名/open-api/asset/resources/data-tag
  • 请求方式: POST
  • 请求参数:
    • Header
      • x-token 字符串,必填项,通过上面第三步得到的数据访问令牌
    • Body
      • key 字符串,必填项,数据访问标签,可在个人中心 > 审批管理 > 我已申请中点击审批通过的数据标签查看
      • format 字符串,非必填项,要求返回的结果格式,可用的取值和含义如下:
        • CSV_WITH_HEADER 格式是 CSV,首行是列名,默认值
        • CSV 格式是 CSV,没有列名首行
        • JSON 作为完整的 JSON 对象数组返回,每行查询结果一个 JSON 对象
        • JSON_ROWS 每行查询结果返回一行,一行是一个 JSON 对象
      • timeout 查询超时时间,非必填项,单位秒,为 0 时表示不限时间
      • ids 字符串数组, 源数据的id列表,非必填, 最大可查询100个
      • tags 字符串数组, 标签值列表,非必填, 最大可查询100个
      • page 获取数据页数,非必填项,默认为1
      • size 获取数据数量,非必填项,默认为1000
  • 返回数据:
    • key_index 字符串类型, 源数据标识
    • obj 字符串数组, 标签信息对象,即标签值的关联对象
    • tag 字符串数组, 数据标签,即标签值

调用示例

Curl调用示例
curl -L -X POST "http://域名/open-api/asset/resources/data-tag" -H "Content-Type: application/json" -H "x-token: eyJ0eXAiOiJKV1QiLC..." -d "{ \"key\": \"17293990834...\", \"timeout\": 15, \"page\": 1, \"size\": 10 }"
正常调用应答示例:
 [
{
"key_index":"30",
"obj":["广州"],
"tag":["发达地区", "南方地区"]
},
{
"key_index":"31",
"obj":["武汉"],
"tag":["发达地区", "中部地区"]
}
]

5. 数据服务访问

接口地址: 当数据服务资产被审批通过时, 接口地址可以在个人中心-审批管理-审批详情-数据服务详情-API Path中查看,如下图: API参考

接口说明

  • 请求地址: http://域名/open-api/asset/resources/data-service/xxxx
  • 请求方式: POST
  • 请求参数:
  • Header
    • x-token 字符串,必填项,通过上面第三步得到的数据访问令牌
  • Body
    • pageSize: 数字类型,分页大小. 当数据服务返回结果分页开启时必填. 最小值1, 最大值100
    • pageNum: 数字类型,当前页码. 当数据服务返回结果分页开启时必填. 最小值1
    • 条件参数: 在数据服务请求参数中配置的参数. 若在配置页面中, 请求参数必填, 则该请求参数不可为空。
注意

注意: 当返回结果参数关闭, 且条件参数为空, 即没有任何请求参数时, 请求体也必须存在, 为’{ }’。 

  • 返回状态码(Http header):

    • 200: 请求成功;
    • 405: 请求超过频率限制
    • 500: 请求失败, 失败原因可解析body获得
  • 返回body:

    • code:数字类型, 请求状态标识, 200表示成功, 其他状态码表示请求失败
    • message : 字符串类型, 返回提示. code为200时, message值为’success’, 其他code值时提示失败原因
    • data : 数组类型, 数组元素为对象类型, 返回结果载体
    • pageSize : 数字类型,分页大小. 当数据服务返回结果分页开启时返回该字段
    • pageNum : 数字类型,当前页码. 当数据服务返回结果分页开启时返回该字段
    • total: 数字类型, 数据总量. 当数据服务返回结果分页开启时返回该字段
错误码提示信息
50008021不能识别的令牌
50008022令牌校验失败
50008023令牌超出有效期
50001092用户已冻结
50008109无权限
50001201参数不可为空
50001200参数校验失败
50008112资产不可用
50008099消费数据异常
分页请求参数示例:
{
"name": "akx_806",
"code": "426185",
"pageNum": 1,
"pageSize": 10
}
分页返回参数示例:
{
"code": 200,
"message": "success",
"pageNum": 1,
"total":1,
"pageSize": 10,
"data": [
{
"float_field": 0.14115502644101385,
"object_id_field": "665d7ef199b590ca4b681399",
"dict_field": null,
"list_field": "7,10,7,3,9",
"int_field2": 978597,
"datetime_field": "2024-06-04",
"string_field1": "ask_602",
"string_field": "akx_806",
"string_field2": "qqq_885",
"bbb_field": "bbb",
"string_field3": "zzz_639",
"bool_field": null,
"int_field": 666692,
"id": "665d7ef199b590ca4b68139a",
"aaa_field": "aaa"
}
]
}
非分页请求示例:
{
"string_field": "akx_806"
}
非分页返回示例:
{
"code": 200,
"message": "success",
"data": [
{
"float_field": 0.29864551553962027,
"object_id_field": "665d7f7e99b590ca4b682db3",
"dict_field": null,
"list_field": "9,2,9,7,6",
"int_field2": 900025,
"datetime_field": "2024-06-04",
"string_field1": "ask_634",
"string_field": "akx_806",
"string_field2": "qqq_926",
"bbb_field": "bbb",
"string_field3": "zzz_401",
"bool_field": null,
"int_field": 426185,
"id": "665d7f7e99b590ca4b682db4",
"aaa_field": null
}
]
}
错误返回示例:
{
"code": 50001204,
"message": "'int_field'不支持参数'aaaa'"
}