- 你是否也想用Smartbi获取其他系统数据进行分析?
- 你是否在为如何对接其他系统的取数接口而烦恼?
- 你是否对Smartbi从其他系统取数的功能不甚了解?
特别说明:在寻找实现方案前,需要先明确系统调用的主体,若为Smartbi系统调用其他系统的接口获取数据,则为本文接下来要叙述的内容。
一、Smartbi支持的API取数功能
1、Smartbi支持的接口取数功能
目前Smartbi仅支持三种API接口的取数方式,即数据模型的接口查询、ETL的python节点、ETL的API取数节点,两者有较大区别。
注:ETL功能需采购ETL模块才能正常使用,若未采购则只能通过接口查询的方式处理。
数据模型接口查询:
接口查询可以使用自定义的代码来实现接口的数据获取、数据解析,只需要按照实现Smartbi的接口,将数据按标准的格式返回就可以被Smartbi解析。可调用 WebService 接口、HTTP请求接口、Java接口等。
Smartbi 数据模型支持添加 2 种接口查询:Java查询、脚本查询,两者使用时区别也非常大。
- Java查询:
- Java查询支持调用WebService 接口、自定义Java类两种,常用的是自定义Java类,这种方式需要在扩展包中实现Smartbi的IJavaQueryData接口,需要有较强的代码能力,以及熟悉Smartbi的扩展包体系。
- 脚本查询:
- 脚本查询使用了Rhino工具包,可以让Java系统执行JavaScript脚本,遵循JavaScript的语法,通过调用Smartbi中的Java类来实现特定的查询逻辑。
API取数节点:
ETL中的API取数节点主要是用来调用HTTP请求的接口,包括HTTP请求衍生出来的RESTful API、Fask API等HTTP请求标准。可以直接通过配置是方式直接发送,使用简单。缺点是灵活性较差,仅限调用HTTP请求的接口。
python节点:
python节点支持通过自定义python代码的方式来获取到接口,其功能和接口取数类似,但是相对来说更加灵活,不像Java查询需要自定义Java Bean,也不需要实现取数接口。python节点取数完全依赖python代码,以及python环境上第三方模块包。
2、如何选择合适的取数功能
当前场景适合使用什么接口取数的场景是需要从多个角度综合评估的,可从以下的角度进行考量。
对比角度
|
API取数节点
|
python节点
|
接口查询
|
上手难易程度
|
容易
|
中等
|
难
|
HTTP请求
|
√
|
√
|
√
|
Java SDK
|
×
|
√
(第三方库jpype实现)
|
√
|
多轮请求
|
√
|
√
|
√
|
特殊加密逻辑
|
×
|
√
|
√
|
二、详解API取数节点
1、HTTP请求简介
HTTP请求由请求行(Request Line)、请求头(Request Headers)、空行(Blank Line)和请求体(Request Body)四部分组成,其中请求行包含方法、路径和协议版本,请求头传递元数据,空行分隔头部与正文,请求体用于传输数据(如POST请求)。
(1)请求行(Request Line)
请求行中包含请求方法、路径、HTTP版本,格式参考:GET /index.html HTTP/1.1。
(2)请求头(Request Headers)
请求头中需要传入一些键值对,常用来传递客户端环境及请求参数。
常见字段
通用头部:Cache-Control(缓存策略)、Connection(连接管理)。
请求专用:Host(目标域名)、User-Agent(客户端信息)、Accept(支持的响应类型)。
实体头部:Content-Type(请求体格式,如application/json)、Content-Length(请求体大小)。
(3)空行(Blank Line)
(4)请求体(Request Body)
请求体主要是用来携带参数信息的,相比与请求行能携带更多的参数信息。注意:仅POST、PUT等需提交数据的请求包含请求体,GET请求通常无请求体。
请求体中的数据要根据请求体中指定的请求格式Content-Type参数进行排列,服务器端读取的时候会按照对应的格式进行读取,若传递方式不对则可能导致请求异常。另外就是Content-Type通常还可以约定编码方式,如Content-Type : application/json;charset=utf-8。
常见的Content-Type值如下:
表单数据:application/x-www-form-urlencoded(如name=张三&age=25)
JSON数据:application/json(结构化数据,如{"name":"张三","age":25})
文件上传:multipart/form-data(支持二进制)
纯文本格式:text/plain
XML格式:text/xml
2、API节点
API节点的配置其实就是配置前面HTTP请求中可以进行修改的请求行、请求头、请求体这三个步骤,不同的接口一般会有不同的要求,一般情况下只需要按照文档进行配置即可。
  
3、案例讲解
注意:文档中使用到的接口仅供学习参考,实际生产时请以提供的接口为准,另外以下请求接口地址中忽略了请求的ip和端口即缺少:http://localhost:8080/ 实际调用时会补上。
(1)get请求
接口地址
|
/api/data/{resid}?name=
|
提交方式
|
GET
|
格式
|
application/json
|
编码
|
UTF-8
|
请求行入参 Request Line
|
resid
|
资源id
|
name
|
资源名
|
在RESTful api的请求中,在请求地址中传递参数是比较常见的,如上述请求文档中的 resid 就是一个典型的例子,另外还有普通的get请求,会在字符 ? 后面拼接请求的参数信息。
上述请求在API取数节点中配置如下:

(2)Post请求
接口地址
|
/api/data/form
|
提交方式
|
POST
|
格式
|
Application/x-www-form-urlencoded
|
编码
|
UTF-8
|
请求体参数
|
resid
|
资源id
|
name
|
资源名
|
post请求的参数一般是携带在请求体中,所以在设置API节点的时候需要在body中传入参数信息,且在form表单中要设置x-www-form-urlencoded来携带参数信息,设置了之后再Headers中就会默认加上对应类型的Content-Type参数,另外设置Content-Type参数时需要注意设置好对应请求的字符集,避免中文乱码。
  
接口地址
|
/api/data/json
|
提交方式
|
POST
|
格式
|
application/json
|
编码
|
UTF-8
|
请求体参数
|
resid
|
资源id
|
name
|
资源名
|
和使用form表单提交数据类似,使用json提交数据时也是将参数放在请求体中,设置时参数类型选择row->json,设置完成后headers中就会默认携带上Content-Type参数,其值为application/json,同样值的注意的是需要设置请求的字符集,否则可能会导致中文乱码。
  
三、API节点参数应用
通过API取数节点发送请求的时候,请求中携带的参数大多数情况下不是一成不变的,需要根据不同的情况进行调整,而如果每次都通过手动修改传递的参数值,那就很难实现取数的自动化。所以此时就需要能够设置一个动态的参数来保证请求参数能够进行动态变化。
1、API取数节点不同请求参数使用
要设置动态参数的映射需要在etl的参数管理中新增一个参数,如下图,这里新增了一个固定值的参数resid,如果要设置为动态的参数也可以设置为全局的公共参数,在公共参数中可以写sql来动态参数参数值。而API节点中要拼接resid参数的位置则需要使用 ${resid}来进行替换。
 
(1)请求行参数

(2)请求体
请求体的参数中通过json传输数据的时候需要注意如果是字符串的时候参数前后的字符串引号不可以去掉。因为底层只会讲参数位置进行字符串替换,替换之后若在json中没有字符串的引号,在json解析的时候就会出现异常。
 
2、示例场景
(1)首先需要在公共设置参数管理中定义一个日期参数,参数中使用sql语句来获取当前日期的字符串。
  
(2)配置好参数之后,此时则需要在etl的参数管理中创建日期参数,并且让参数映射当公共参数中定义好的获取当前时间的参数,注意选择参数后参数值不要选择,不选择的情况下菜表示为动态参数,若选择了值,就无法实现动态的效果。

(3) 配置参数到取数请求中,这样发送请求的时候就会先执行参数sql获取当前时间然后再将当前时间传入到请求参数中。

四、接口权限校验(身份认证)
由于权限管控、审计、数据安全等各种需求场景,一般情况下API的取数接口都可能会有登录认证的逻辑,需要按照需求先完成登录之后才能顺利获取到数据。当需要多次交互时,就需要使用到“循环API节点”。循环API节点可以根据上游节点的数据作为参数传入到本地调用的请求当中,还可以根据上游节点返回的多个结果值进行循环取数,这就能够满足多次交互的需求了。
1、多请求交互示例
(1)示例接口详情
当前示例实际的请求获取数据的接口是 /api/data/by/token,在发送该请求时参数信息中要传递用户登录信息的令牌,而这个令牌需要通过 /api/data/token 接口来获取,这种就是典型的多次交互场景。
/api/data/token 接口信息
接口地址
|
/api/data/token
|
提交方式
|
POST
|
格式
|
application/json
|
编码
|
UTF-8
|
请求体入参
|
username
|
用户名
|
password
|
密码
|
返回体
|
code
|
请求状态码
|
data
|
登录令牌
|
/api/data/by/token 接口信息
接口地址
|
/api/data/by/token
|
提交方式
|
POST
|
格式
|
application/json
|
编码
|
UTF-8
|
请求体入参
|
token
|
登录令牌
|
catalogId
|
资源id
|
返回体
|
code
|
请求状态码
|
data
|
资源详细信息
|
(2)调用流程
第一步:先配置一个api取数的节点来来获取用户的登录令牌。

第二步:使用json解析节点来解析返回的json数据,从json数据中获取到返回的令牌数据。
 
第三步:设置循环API节点的循环配置,一键映射之后,上游的data字段的数据就会被映射为参数data,这样后续在使用 ${data} 就可以将数据拼接到请求中了。
 
第四步:配置好循环方式之后就可以来配置请求的调用了,第二个请求的token由上一请求调用的结果进行传入,配置为参数 ${data} 即可,实际调用时会替换为上一请求的结果。
 
2、复杂登录场景
在取数的场景中,很少会有明文传递用户名密码的方式,大多数情况下都需要进行加密之后再传输,避免用户名密码被泄露。另外还有集成统一认证平台的,通过CAS、Oauth2等方式来通过登录认证,这种登录方式就更加复杂。在面对这些复杂的登录方式时,简单的发送请求已经无法满足需求了,此时就可以使用最后是杀手锏——"python节点",下面我们用账号密码通过DES加密完成登录的示例来抛砖引玉,详细了解一下其调用流程。
(1)示例接口详情
如下演示的请求接口文档,接口中的登录信息token换成了需要des加密之后的用户信息,所以我们需要在之前完成des令牌的加密。
/api/data/des接口信息
接口地址
|
/api/data/des
|
提交方式
|
POST
|
格式
|
application/json
|
编码
|
UTF-8
|
请求体入参
|
token
|
des加密之后的登录令牌
|
catalogId
|
资源id
|
返回体
|
code
|
请求状态码
|
data
|
资源详细信息
|
(2)实现示例
第一步:使用python节点加密令牌,这里选用第三方库PyCryptodome来完成DES加密,加密得到是结果最终作为DataFrame进行发回,运行节点后就得到了加密的令牌。
  
参考加密代码 :

第二步:通过使用循环API节点映射上游节点的参数,然后通过参数的形式设置到API请求当中,如下图:
 
基于Python节点就能实现复杂的逻辑调用,并且实现多次请求的流程,在Python代码中也可以定义特殊的取数逻辑。
3、获取返回体的请求头信息
在实际调用接口的场景时,请求返回的信息并不完全是通过返回体进行返回,有些会话状态的信息可能存储在返回体的cookie、session中,这个时候就需要对返回体的响应头信息进行解析了,那我们在API取数中要如何获取到响应头的信息呢。
如果要获取到响应的头信息,我们可以在API配置中勾选上输出响应头,勾选了之后节点执行的结果就会多一列responseHeaders,里面就可以拿到响应头的信息,如服务器端设置的cookie的信息,通过json解析之后就可以再设置到下一个请求当中去。
 
恭喜你已阅读完全文,来做做题巩固下学习内容,答题可赢取麦豆哦——>点击领取任务 |