Oracle APEX 系列文章18:如何利用REST数据源进行APEX开发

前言

在现实工作中,很多时候需要将第三方的系统数据集成到自己的系统中,但第三方系统使用的数据库不是Oracle数据库,甚至不在本地局域网内,无法简单地通过数据库直连的方式集成到APEX中。但对方可能会提供基于http的接口,如: SOAP Web Service或者RESTful风格的API。

钢哥注: 不了解REST API与SOAP的区别的可以看这里:比较SOAP与REST API

其实,APEX提供将RESTful API作为数据源的能力,这种方式可以不用管后端数据源是什么数据库,只要通过合法调用RESTful API,即可实现对远端数据的增删改查(前提是对方得提供增删改查的RESTful API),甚至可以实现定时同步远端数据(到本地表),从而扩展APEX数据源。很多APEX标准控件(如:Interactive Grid,Interactive Report, Classic Report)都支持使用REST作为数据源,开发者无需关心背后的数据是否来自”本地“,就可以像使用本地表一样进行页面开发,可以说还是非常不错的。

下面就跟钢哥一起揭开APEX使用REST Data Source的神秘面纱吧。

应用场景

一般而言,对方系统提供的接口是直接暴露到公网上的,为了安全起见,在调用时都需要对调用方的身份进行验证。如果是非法调用,接口是不会正常返回结果的。常见的几种验证方式有:基本用户名密码验证、Oauth2、请求头信息等。

在使用APEX进行接口调用开发之前,需要先按照对方提供的接口说明,使用接口调试工具,如:Postman, Postwoman,对目标接口进行必要的测试,确保接口的可用性及调用参数的合法性。

接口调试

本文假设对方提供了2个接口,一个是通过用户名和密码获取合法token,另一个是我们系统真正要使用的数据接口,用来查询系统数据的。

  • 接口1(登录接口): 通过用户名密码获取合法的调用token。注意:这里要严格按照对方提供的接口要求进行传参。例如:对方要求使用POST的方式调用这个接口,同时需要提供两个参数fLoginnamefPassword,按照要求填写到接口测试工具中,点击”Send”按钮进行接口测试。

如果一切顺利,对方将会返回预期的结果,如下图所示:

可以看到,login接口已经返回了我们需要的token值,后续调用其他接口时,需要带着这个token。

  • 接口2(用户信息查询接口): 根据接口说明手册要求,这个接口需要在请求头(Request header)里添加一个固定参数Authorization,并且传递一个合法的token值(刚刚第一个接口获取到的)。

如果不提供合法的token,直接调用接口2,返回结果如下图所示:

利用登录接口中返回的合法token值,将请求头信息补全后再次进行测试,可以看到,接口成功返回了预期内容。

接口封装

但这个token是有时效性的,过一段时间就会失效。现实中,我们不可能每次都手工获取token并填入其他接口后再进行调用,所以需要简单地对获取token的请求进行一下封装,以便简化接口调用的步骤。

钢哥提示: 利用PL/SQL函数将登录接口调用过程进行一下封装,这样以后要获取合法的调用token,只需要执行一下这个函数即可。也可以将返回结果保存到表或者APEX的Application item中,方便后续引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-- 获取token函数
create or replace function hfja_get_rest_token return varchar2 as
l_clob CLOB;
l_token varchar2(4000);
j apex_json.t_values;
begin
-- 初始化请求头信息
apex_web_service.g_request_headers(1).name := 'Accept';
apex_web_service.g_request_headers(1).Value := '*/*';
apex_web_service.g_request_headers(1).name := 'Content-Type';
apex_web_service.g_request_headers(1).value := 'application/x-www-form-urlencoded';

-- 组装好RESTful API需要的初始化参数,发起http请求,并将返回结果保存到clob变量中
l_clob := apex_web_service.make_rest_request(
p_url => 'http://xxx.xxx.xxx.xxx:8090/SubstationWEBV2/user/login', --此处替换成你自己的RESTful API地址
p_http_method => 'POST', --选择合适的请求方法
p_parm_name => apex_util.string_to_table('fLoginname:fPassword'), --用冒号分隔请求参数名称
p_parm_value => apex_util.string_to_table('test:123456') --用冒号分隔请求参数对应的传入值
);

-- 将clob类型的结果装换成json格式,方便截取返回结果中的关键信息
apex_json.parse(j, l_clob);

-- 获取真正需要的信息(token)
l_token := apex_json.get_varchar2(p_path=>'data.token', p_values=>j);
return l_token;

exception
when others then
dbms_output.put_line('sqlerrm='||sqlerrm);
return '';
end;

简单调用测试一下,能够成功取到合法的token。

1
2
3
4
-- 调用函数实时获取token
begin
dbms_output.put_line(hfja_get_rest_token);
end;

创建REST数据源

进入到APEX应用中,选择共享组件 -> REST数据源,从头创建一个REST数据源。

这里的URL就是要调用的REST接口地址。

直接下一步

这一步需要提供接口验证方式。

未提供合法验证方式的结果,APEX无法帮助我们自动生成配置。虽然配置信息后续可以手工创建,但为了简化后续步骤,最好还是提供一下正确的验证方式。

验证方式分为以下几种:

  • Basic Authentication:基本验证,是指在页面表单上输入用户名和密码的方式;
  • OAuth2 Client Credentials Flow:OAuth2方式,一般像微信、钉钉等互联网应用常用的验证方式;
  • Oracle Cloud Infrastructure (OCI):Oracle云自带的验证方式;
  • HTTP Header:在请求头信息中附加验证信息的方式;
  • URL Query String:在url上附加参数的方式。

我们这里选择HTTP Header,并按照接口要求提供正确的参数名和token值,点击Discover按钮。

可以看到,这次接口调用成功了,并且APEX自动返回了结果数据让我们预览。点击Create REST Data Source按钮进行REST数据源的创建。

创建完成后,如下图所示。除了刚刚我们自己输入的信息外,一个REST数据源还包括Data ProfileOperationParameters几个部分。

点击Edit Data Profile按钮,查看APEX为我们自动生成的接口数据基础信息。

这里需要注意的是Format(返回的数据格式)和Row Selector(结果选择器)。一般来说,REST接口返回的数据都是JSON格式的,而Row Selector里的节点代表我们要返回的数据的根节点。

另外还可以对每一个字段进行编辑,可以将不需要的字段隐藏掉(Visible设置成No),还可以设置主键字段(后面会讲到)。

返回REST数据源信息页面,在右边有一个Manage Synchronization的链接,这个链接可以进入到数据同步页面,方便我们创建定时同步任务,以便将远端REST数据定时同步到我们本地的表里。

由于本地表还没创建,选择New Table选项,并输入表名,创建一个数据同步表,点击Save按钮后,APEX会提示当前表不存在,并贴心地帮你生成好了建表的SQL语句。

点击Show SQL按钮可以查看APEX自动生成的建表语句,点击Create Table就可以自动创建数据同步表了。

数据同步

数据同步表创建好后,就可以点击Save and Run按钮尝试进行数据同步了。

钢哥注: 这里有一个小问题,点击数据同步按钮后,同步状态一直显示Running,实际已经同步好了,只能通过刷新页面看到结果,不知道是不是bug。

查看同步log,发现数据同步失败了,提示500错误。这是因为我们没有提供合法的token造成的。

点击Add Step按钮添加一个同步步骤,

填写必要的HTTP Header信息:

  • 参数名称: Authorization
  • 值类型: PL/SQL函数体
  • 表达式: return hfja_get_rest_token;

这样就可以在同步的时候自动获取合法token了。

再次执行数据同步操作并检查日志,可以看到这次数据同步成功了。

切换到SQL Workshop -> Object Browser,查看数据同步表,可以看到远端数据已经同步到本地表里了。

在同步页面还有一个Synchronization Type(同步选项)需要注意,有3个选择:

  • Append: 追加方式同步,每次同步都执行插入;
  • Merge: 合并方式同步,根据主键自动判断是否需要插入还是更新;
  • Replace: 替换方式同步,每次同步前都删除之前的数据,重新插入。

我们选择第二种合并方式。

页面提示我们的REST数据源(返回的结果集)中没有提供主键,所以还需要修改一下Data Profile

点击Edit Data Profile对REST数据源返回结果进行编辑。

明确指定返回数据集中的主键列。

对本地表也进行相同的修改,设置好主键列。

设置好以后,就可以选择Merge同步选项了,再次同步测试一下,发现数据也是正确的了。

创建页面

在APEX中创建一个页面,新增一个Region

将控件类型设置成能够使用REST数据源的控件,如:Interactive Report

  • Location: REST Source
  • REST Source: UserCommonInfo(我们之前创建好的REST数据源)

需要注意,如果我们不勾选Use Sychnoronization table选项,意味着我们是从远端REST接口查询数据,此时就必须要设置一下控件的参数。

将参数Authorization设置成通过我们自己的PL/SQL函数获取合法token。

运行页面,可以看到数据已经加载到页面上了。

勾选Use Sychnoronization table选项,重新运行。

此时数据看起来是一样的,但实际上是使用的我们同步到本地表的数据。

结论

通过以上的步骤,就可以将远端REST接口作为APEX新的数据源,通过数据同步的功能,使远端的数据可以定时同步至本地表,这样就变相地实现了跨系统的数据集成。

以上仅仅是对REST Data Source这一新特性的简单使用。由于时间关系,对这一新功能了解得还不够,如有疏漏或错误,还请大家指正。

钢哥的 Oracle APEX 系列文章:

本文标题:Oracle APEX 系列文章18:如何利用REST数据源进行APEX开发

文章作者:王方钢 / Kenny Wang

发布时间:2021年09月15日 - 22:09

最后更新:2021年09月16日 - 00:09

原始链接:https://wangfanggang.com/Oracle/Oracle-APEX/apex-series-18/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

王方钢 / Kenny Wang wechat
0%