You need to enable JavaScript to run this app.
导航
REST API 2.0算子
最近更新时间:2025.09.17 16:39:32首次发布时间:2025.09.17 16:39:32
复制全文
我的收藏
有用
有用
无用
无用

REST API 2.0调用是特色专区算子中的各类请求处理工具,可将上游节点的输出数据作为API的入参,查询数据进行数据补全。本文将介绍如何使用REST API 2.0调用算子。

操作步骤

新建REST API 2.0

  1. 点击「数据管理」,选择「可视化建模」,点击「新建」,选择「新建离线任务」。
    Image
  2. 按照任务创建中的步骤完成离线任务创建,在处理节点时,选择为数据连接添加「特色专区算子」中的REST API 2.0调用。
    Image

配置基本信息

在基本信息页面,配置相关参数:

参数

说明

URL 地址

填写需要连接的 API 的完整网址。支持cURL的导入导出。

请求方式

支持GET、POST两种请求方式。

  • GET:用于获取资源,参数附在URL中
  • POST:用于提交数据,参数通过请求体传递

OAuth2认证

支持 OAuth2 授权码模式。

注意

当 API 请求需要访问采用 OAuth2 授权码模式的第三方服务接口时启用此功能。

参数设置

构造完整的 API 请求参数,包括请求头、请求参数、请求体、前置操作及后置操作。

高级设置

支持用户对超时时间、重试次数和分页等内容进行设置。

配置URL 地址

填写需要连接的 API 的 URL 地址。您可以手动填写,也可以通过cURL导入的方式完成URL地址、请求方式和参数设置部分的填写,对于填写好的相关配置,也支持cURL格式导出。

说明

curl是一个命令行工具,用于通过各种网络协议(如 HTTP、HTTPS、FTP 等)传输数据。它支持发送请求、接收响应,并可以携带参数、认证信息或文件内容。示例如下:

curl -X POST "https://api.example.com/import" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "name": "John Doe",
    "email": "john@example.com"
  }'

Image

  • cURL导入:点击「cURL」按钮,在弹出的「通过cURL导入」窗口中粘贴需要导入的cURL内容,点击「解析并导入」,系统将会自动识别其中的URL地址、请求方式和参数设置信息,并填写到相应位置。
  • cURL导出:手动配置好URL地址、请求方式和参数设置等信息后,如果需要导出为cURL格式,点击「导出」,在弹出的「导出cURL」窗口中,点击「复制」,系统将会将自动生成cURL格式内容复制到剪贴板中。

配置请求方式

支持GET、POST两种请求方式。

  • GET:用于获取资源,参数附在 URL 中
  • POST:用于提交数据,参数通过请求体传递

配置OAuth2认证

支持 OAuth2 授权码模式。

注意

当 API 请求需要访问采用 OAuth2 授权码模式的第三方服务接口时启用此功能。

  1. 点击授权,打开侧边栏,在此输入授权基础信息(AK、SK和授权跳转地址),具体获取方式见相关三方网站文档,配置完成后点击「下一步」。
    Image
  2. 如果用户是第一次利用该AK和授权跳转地址组合配置授权信息,需要进一步获取AccessToken配置和RefreshToken配置。配置API地址、请求方式、请求参数、返回参数等相关信息,点击确认后浏览器自动发起请求授权链接,跳转三方授权页面。
    Image
  3. 用户完成授权后,自动回调ABI统一授权回调地址。ABI回调会根据先前用户的授权配置,后台同步发起【获取Access Token】【获取Refresh Token】请求,校验通过后配置生效,回到数据连接页即可见完成授权。

    注意

    • 三方网站授权通常针对单个 AK 维度,多个数据链接若使用同一 AK,需共享同一个授权。
    • 系统会根据授权链接 host 和 AK 自动匹配有效授权;若无,则需首次配置。
    • 系统无法校验三方出参(无统一格式),请仔细检查参数,避免因参数错误导致接口返回失败。若授权地址和 AK 相同,系统将自动匹配上次配置,错配数据只能订正后重新配置。
    • 【获取Access Token】回调请求中 code 对应的参数 key 固定为 “code”,无法修改。

配置参数

参数设置部分通过标准化流程引导用户配置 API 请求的基本信息,包括请求头、请求参数、请求体,以及前置/后置操作。系统提供了内置变量和内置函数,具体可参考系统内置变量系统内置函数

说明

参数value支持静态参数值、动态参数值,具体填写规范如下:

  • 静态参数值:填写API参数的具体值即可,如“male”。
  • 动态参数值:请按照${params}格式填写,其中params指的是「前置操作」输出字段的名称,该字段下的值将作为API参数的入参值。如以下场景,假设API的入参是object_id,要将「前置操作」中的字段unit_id的值作为object_id的入参值,那么API配置中,key是object_id,value是${unit_id}。
  • 请求头:支持配置key、value,支持添加、删除操作,最多可配置10组。

  • 请求参数:输入API所需的所有查询参数。

  • 请求体:选择请求体类型(form-data或raw),均支持用户输入JSON格式的请求体。
    总则:对JSON进行操作,$表示根节点,.号表示取子节点。
    如果JSON数据为:

    {
      "showapi_res_error": "",
      "showapi_res_id": "6597a2f5fb638cf45b4d460c",
      "showapi_res_code": 0,
      "showapi_fee_num": 1,
      "showapi_res_body": {
        "list": [
          {
            "time": "14:26:57",
            "zhesuan": "193.69",
            "code": "AED",
            "hui_out": "195.91",
            "chao_in": "192.95",
            "chao_out": "199.47",
            "name": "阿联酋迪拉姆",
            "hui_in": "194.55",
            "day": "2024-01-05"
          },
          {
            "time": "14:26:57",
            "zhesuan": "477.56",
            "code": "AUD",
            "hui_out": "481.77",
            "chao_in": "478.08",
            "chao_out": "483.16",
            "name": "澳大利亚元",
            "hui_in": "478.57",
            "day": "2024-01-05"
          }
        ],
        "listSize": 28,
        "ret_code": 0
      }
    }
    

    则一些路径对应的值结果取值如下:

    $.showapi_fee_num = 1
    $.showapi_res_id = "6597a2f5fb638cf45b4d460c"
    $.showapi_res_body.list.* = [{"time":"14:26:57","zhesuan":"193.69" ... // 后面省略
    
  • 前置操作:​当您需要在主请求之前执行一些额外的步骤来准备数据或获取必要的信息时,可以通过该配置来完成。
    Image

    注意

    最多可以设置5个前置操作。

    1. 点击「+新增前置操作」,在配置页面需要输入前置操作的详细信息,包括URL地址、请求方式等。
      Image
    2. 点击“发起请求”后,系统将解析这个前置请求,并将解析结果呈现在「请求结果」区域,用户需要配置动态参数的key和结果字段路径,方便后续将前置请求结果应用于当前请求。动态参数编写可参考动态参数编写规则
  • 后置操作
    提供一种更加灵活和强大的自定义参数配置方式,支持 groovy语法,支持用户编写代码实现多层次的请求解析。后置操作编写规则可参考后置操作编写规则

配置高级设置

支持用户对发送请求的超时时间、重试次数和分页等内容进行设置。

参数

配置说明

并行度

该并行度设置的是Spark任务单个Partition的并行度,实际最终并行度受该任务分配的Partition个数影响,实际执行时的并行数和集群可用的资源有关。建议用户根据调用的接口性能(QPS、QPM等限制),合理计算并行度进行填充。默认为1。

超时时间

输入请求在没有响应时等待的最长时间(单位:毫秒),默认为3分钟。

重试次数

当请求失败,系统尝试重试的次数,最多支持5次。

请求间隔

任务的最终QPS取决于输出节点分配的core数目和请求间隔,调整请求间隔能够控制任务并发。请求间隔越小,QPS越大。

注意

请谨慎设置请求间隔,并发过高时有服务风险(当单任务的QPS>全局QPS,以全局QPS为准)

补全异常处理

  • 终止任务:如果调用失败会导致任务失败,并清除中间结果。
  • 忽略异常:忽略调用失败的数据,使用null填充,保留调用成功的结果,任务成功,宽容模式。

配置解析请求与路径

  1. 在完成上述配置操作后,您可以点击“发送请求”,系统将解析请求。
    解析的顺序为「前置操作」>「当前请求」>「后置操作」,并将呈现「解析结果」。
    Image

  2. 在系统完成解析请求后,用户还需要完成路径配置操作,包括设置字段路径、设置字段以及数据预览。
    Image

    参数

    配置说明

    字段路径

    输入字段路径,使用$表示根节点,.号表示子节点。点击“获取字段”按钮,系统将解析并展示“字段配置”区域。
    这里配置的是解析结果的根路径,规则如下:

    • 根路径指向 必须是一个Map或者Array,否则无法解析出字段的key。
    • 如果指向的是 Array,则必须写成能解析出key的形式,例如以.* 结尾,例如$.list.*,不得直接写成$.list,这样解析不出key。
    • 配置完成后,点击获取字段,只会解析出该路径下的第一层字段结构,且这些字段都为基本数据类型。

    示例:

    // 取整个结果,结果在字段包括:showapi_res_error、showapi_res_id、...、showapi_res_body
    $
    // 取数组中的内容
    $.showapi_res_body.list.* = [{"time":"14:26:57","zhesuan":"193.69" ... // 后面省略
    

    字段配置

    使用“添加”按钮支持新建字段,解析逻辑基于您输入的 rootPath 为基准,解析出结果。同时,支持删除已配置的字段。
    这里配置的是解析根路径后获取的最终字段的路径,同时也是该数据连接的最终字段结果。

    注意

    对于根路径为数组的情况,如果字段路径前缀和根路径不一致,则最终生成的结果集中,会把该字段对应的值计算出来后直接加到数组的每一个元素中。
    例如,对于天气数据,根路径为 $.forcast15days.list.* ,表示未来15天的天气,用户再添加一个 $.city 的字段代表城市,则最终会把 $.city 的值计算出来后,直接加到每一个未来天气的数据里去作为一个叫做city的key。其值在数组里的每一项都是相同的。

    数据预览

    点击“数据预览”按钮,支持查看当前选中字段的前100行明细数据。

测试执行

点击「测试执行」,测试成功后,点击「保存」即可完成当前数据连接所有配置。
Image

相关参考

动态参数编写规则

动态参数和后置脚本都选用Groovy作为脚本引擎。
对于params、body、header、url中出现的 ${},作为 groovy的字符串插值表达式执行获取结果。同时会内置一些自定义函数,例如md5()方法、日期变量等。以下是一些执行结果示例:

假如目前有两个参数,是在前置请求中配置好的,如下:
num1 = 1
num2 = 2

则${}里面的内容会被作为表达式执行,其余部分为普通字符串,下面表达式结果分别为:
abc               // abc
${num1}           // 1
${num1+num2}      // 3
${num1}+num2      // 1+num2
${num3}           // 报错,没有num3参数
${"${num1}"}      // ${num1}

后置操作编写规则

后置操作编写示例如下:

def convertJson(response) {
    /*
    这里填写后置操作代码
    response表示api返回的结果,假设api返回结果为
    {
        "city": "上海市",
        "forcast": [
            {"temperature": 5, "day": "2024-01-01"},
            {"temperature": 6, "day": "2024-01-02"},
        ],
        "test": "test"
    }
    一些代码示例:
    场景1:添加、编辑、循环,为list中每个元素加上city
    ls = response.forcast
    for (i=0; i< ls.size(); i++) {
        ls[i].city = response.city
    }
    场景2:删除某个key
    response.remove("test")
    */
    return response;
}

Image

终止条件编写规则

支持groovy语法,当达到终止条件时不再进入下一页。response代表本次请求的结果。

系统内置变量

系统已经内置的动态参数如下,变量命名时不要和系统变量名重名,否则会被系统变量覆盖。

生效范围:url、header、params、body。在后置操作中无效。

${date} // 日期,格式:yyyyMMdd
${DATE} // 日期,格式:yyyy-MM-dd
${hour} // 小时,格式:HH
${HOUR} // 小时,格式:H
${year} // 年,格式:yyyy
${month} // 月,格式:MM
${day} // 日,格式:dd
${timestamp} // 时间戳,格式:13位时间戳
${last_date} // 上个月最后一天,格式:yyyyMMdd
${last_DATE} // 上个月最后一天,格式:yyyy-MM-dd
${last_day} // 上个月最后一天,格式:dd

以上变量支持日期加减,例如 ${date-1},代表前一天

系统内置函数

生效范围:url、header、params、body、后置操作。

使用说明

说明

可以使用免费 接口调试工具 来进行测试。

  • 在系统内置函数的生效范围内,可以使用“${}”语法来使用支持的内置函数以及预定义变量(花括号中的内容为Grovvy表达式)。
  • 支持多行语句,多行语句使用英文分号分隔;当使用多行表达式时,最终值为最后一个表达式的返回值。
  • 示例:
    • URL中添加md5值和当前系统时间戳

    • 请求头中添加复杂表达式计算的值

摘要函数

String md2Hex(String data);
String md5Hex(String data);
String shaHex(String data);
String sha1Hex(String data);
String sha256Hex(String data);
String sha384Hex(String data);
String sha512Hex(String data);

byte[] md2(String data)
byte[] md5(String data)
byte[] sha(String data)
byte[] sha1(String data)
byte[] sha256(String data)
byte[] sha384(String data)
byte[] sha512(String data)

数学函数

java.lang.Math 相关的所有函数

获取日期时间、格式化、日期加减

// format: 格式化日期为字符串。
currentDate = new Date()
formattedDate = currentDate.format('yyyy-MM-dd HH:mm:ss')

// plus 和 minus: 日期的加减操作。
tomorrow = currentDate + 1 
yesterday = currentDate - 1 

字符串扩展方法

// capitalize(): 将字符串的第一个字符大写。
str = "groovy"
str.capitalize() // 输出: "Groovy"

// reverse(): 反转字符串。
str.reverse()     // 输出: "yvoorg"

// contains(): 检查字符串是否包含指定的子字符串。
str.contains("oo") // 输出: true

// toInteger()、toLong()、toFloat()、toDouble(): 将字符串转换为相应的数值类型。
str = "123"
str.toInteger() // 输出: 123

// split(): 分割字符串。
str = "a,b,c"
str.split(",") // 输出: ["a", "b", "c"]

// isNumber(): 检查字符串是否是一个数字。
str.isNumber() // 输出: true

Collection扩展方法

// each: 对集合的每个元素执行闭包操作。
list = [1, 2, 3]
list.each { println it } // 输出: 1 2 3

// findAll: 筛选集合中满足条件的元素。
list = [1, 2, 3, 4, 5]
evens = list.findAll { it % 2 == 0 }
println evens // 输出: [2, 4]

// collect: 将集合中的每个元素映射为另一个值。
list = [1, 2, 3]
squares = list.collect { it * it }
println squares // 输出: [1, 4, 9]

// sum: 计算集合中所有元素的和。
list = [1, 2, 3]
println list.sum() // 输出: 6

// join: 将集合中的元素用指定的分隔符连接成字符串。
list = ["a", "b", "c"]
println list.join("-") // 输出: "a-b-c"

Map扩展方法

// each: 对 Map 中的每个条目执行闭包操作。
map = [a: 1, b: 2, c: 3]
map.each { key, value -> println "$key: $value" } // 输出: a: 1 b: 2 c: 3

// findAll: 筛选 Map 中满足条件的条目。
map = [a: 1, b: 2, c: 3]
filtered = map.findAll { key, value -> value > 1 }
println filtered // 输出: [b: 2, c: 3]

// collect: 将 Map 中的每个条目映射为另一个值。
map = [a: 1, b: 2, c: 3]
collected = map.collect { key, value -> "$key=$value" }
println collected // 输出: ["a=1", "b=2", "c=3"]

// getOrDefault(Object key, Object defaultValue): 获取指定键的值,如果键不存在则返回默认值。
map = [a: 1, b: 2]
println map.getOrDefault('c', 0) // 输出: 0

// collectEntries(Closure closure): 将 Map 转换为另一个 Map。
map = [a: 1, b: 2, c: 3]
newMap = map.collectEntries { key, value -> [(key): value * 2] }
println newMap // 输出: [a: 2, b: 4, c: 6]

// find(Closure closure): 查找 Map 中第一个满足条件的条目。
map = [a: 1, b: 2, c: 3]
entry = map.find { key, value -> value > 1 }
println entry // 输出: [b:2] 或 [c:3]

// keySet(): 获取 Map 中的所有键。
map = [a: 1, b: 2, c: 3]
println map.keySet() // 输出: [a, b, c]

// values(): 获取 Map 中的所有值。
map = [a: 1, b: 2, c: 3]
println map.values() // 输出: [1, 2, 3]

// flatten(): 将嵌套的 Map 展平。
map = [a: [b: 2, c: 3], d: 4]
println map.flatten() // 输出: [a.b:2, a.c:3, d:4]

List扩展方法

// unique(): 移除列表中的重复元素。
list = [1, 2, 2, 3, 4, 4]
println list.unique() // 输出: [1, 2, 3, 4]

// sort(): 对列表进行排序。
list = [3, 1, 4, 1, 5, 9]
println list.sort() // 输出: [1, 1, 3, 4, 5, 9]

// flatten(): 将嵌套的列表展平成一个列表。
list = [1, [2, 3], [4, [5, 6]]]
println list.flatten() // 输出: [1, 2, 3, 4, 5, 6]

// count(Closure closure): 统计满足条件的元素个数。
list = [1, 2, 3, 4, 5]
println list.count { it % 2 == 0 } // 输出: 2

Range扩展方法

// step(int step): 以指定步长遍历范围内的元素。
range = 1..10
range.step(2).each { println it } // 输出: 1 3 5 7 9

// containsWithinBounds(Object value): 检查值是否在范围内(包括边界)。
range = 1..10
println range.containsWithinBounds(10) // 输出: true

// subList(int fromIndex, int toIndex): 获取范围内指定索引范围的子列表。
range = 1..10
println range.subList(2, 5) // 输出: [3, 4, 5]

// toList(): 将范围转换为列表。
range = 1..5
println range.toList() // 输出: [1, 2, 3, 4, 5]

加密方法

// Base64 编码和解码
// 编码
str = "hello world"
encoded = str.bytes.encodeBase64().toString()
println "Base64 Encoded: $encoded" // 输出: Base64 Encoded: aGVsbG8gd29ybGQ=
// 解码
encoded = "aGVsbG8gd29ybGQ="
decoded = new String(encoded.decodeBase64())
println "Base64 Decoded: $decoded" // 输出: Base64 Decoded: hello world

摘要方法

// MD5
str = "hello world"
md5Hex = str.md5()
println "MD5: $md5Hex" // 输出: MD5: 5eb63bbbe01eeed093cb22bb8f5acdc3

// SHA-1
str = "hello world"
sha1Hex = str.digest("SHA-1")
println "SHA-1: $sha1Hex" // 输出: SHA-1: 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed

// SHA-256
str = "hello world"
sha256Hex = str.digest("SHA-256")
println "SHA-256: $sha256Hex" // 输出: SHA-256: b94d27b9934d3e08a52e52d7da7dabfac484eefc56bf5ef4b102e3d8fdedfb68