通过应用插件自定义更多API

最后更新:2021-12-02

1. 前提条件

IDP平台中提供了很多的API可供使用,包括但不限于以下内容:

我们推荐优先使用平台已有的API能力,减少自定义开发与交付维护成本。只有项目特殊定制较多,平台API不满足情况下,才使用自定义API功能。


要实现通过应用插件自定义更多API,需要先满足以下几个条件:

  1. 按照应用模板插件已经实现了一个可用的应用插件(或者用已经存在的应用插件)。

  2. 参照交付工程师(后端)如何上手使用具备开发能力 (主要是RESTFUL API,Spring MVC与Hibernate)。

下面以应用模板插件实现时提供的demo工程(插件ID:plugin_v2_demo)来进行自定义更多API说明。

2. 如何自定义API

2.1. API规范要求

2.1.1. API URL定义要求

应用插件中不是任何的API URL都支持,必须要符合以下URL前缀的才能支持,具体实现是根据需要选择。

  • 受应用 API access_token保护的URL前缀

    • URL前缀:/api/application/{plugin_id}/,{plugin_id}为具体的插件ID,如:plugin_v2_demo。

    • 示例:/api/application/plugin_v2_demo/is_existed_username

说明:API access_token是指通过应用的API Key与API Secret从IDP获取到的token值。

  • 公开能访问的URL前缀

    • URL前缀:/public/api/application/{plugin_id}/,{plugin_id}为具体的插件ID,如:plugin_v2_demo。

    • 示例:/public/api/application/plugin_v2_demo/system_time

注意:公开能访问的API不需要任何权限,一般用于返回一些非账户的或非管理权限的信息(如系统时间或配置的策略信息)。

2.1.2. API请求method支持

按照RESTFUL API规范,自定义API中支持以下几类method

  • GET,查询API时使用。

  • PUT,更新操作API时使用。

  • POST,增加新数据API时使用。

  • DELETE,删除操作API时使用。

对应Spring MVC中的注解 @GetMapping@PutMapping@PostMapping@DeleteMapping

2.1.3. API响应数据要求

  • 默认API都返回JSON格式的数据(即Controller是使用 @RestController 或 方法上有 @ResponseBody 注解)。

  • 若响应的数据非JSON格式,通过在Controller方法中增加 HttpServletResponse变量,自定义设置响应的contentType来处理。

2.2. 开发API

2.2.1. API定义

下面在插件的Demo工程(IDP4-Application-Plugin-V2-Demo)基础之上增加下面两个自定义API来进行说明。

  • API1:判断传入的用户名(username)在IDP中是否存在。需要token保护。

    • URL定义:/api/application/plugin_v2_demo/is_existed_username

    • 请求method:GET

    • 请求参数:username。示例:/api/application/plugin_v2_demo/is_existed_username?username=lisi

    • content-type:application/json

    • 请求响应:

{
 "success": true,
 "code": "200",
 "message": null,
 "requestId": "xxx",
 "data": {
   "existed": true
 }
}

existed = true 表示用户名存在,false 表示不存在。

  • API2:获取IDP的系统时间值(毫秒数)。公开API。

    • URL定义:/public/api/application/plugin_v2_demo/system_time

    • 请求method:GET

    • 请求参数:

    • content-type:application/json

    • 请求响应:

{
 "success": true,
 "code": "200",
 "message": null,
 "requestId": "xxx",
 "data": {
   "time": 332334422
 }
}

2.2.2. 代码实现

2.2.2.1. web层实现(Controller)

在IDE中打开工程,在包com.idsmanager.plugin.demo.web.controller中新建一个java类,名为:DemoV2CustomAPIController.java。 并按照上面定义的API增加两个Controller方法,如下图:

  • Controller中不处理业务逻辑(最多做一些参数校验),业务均转给service层处理。

  • 每个方法返回的对象都为ApplicationAPIResult,这是插件开发环境中提供的一个包装类,可生成公共的属性值(如 响应JSON中的codemessage), 还有它的子类BFFApplicationAPIResult也会经常使用到。

2.2.2.2. service层实现(业务逻辑)

service层用于业务逻辑实现。在接口DemoV2Service.java类中定义了两个方法,如下图:

在其实现类DemoV2ServiceImpl.java中提供了具体的实现逻辑(该类是一个Spring Bean,类名上增加了注解 @Service),如下图:

  • 该类注入了infrastructure层的Bean(DemoV2CustomRepository.java)用于调用底层数据库的交互逻辑(此处的统计用户数量)。

  • 若需要有数据库的交互,则需要在方法上增加注解@Transactional告诉运行环境需要数据库事务支持, @Transactional(readOnly = true)表示只读事务(只能查询);若不需要事务则不加注解(此处的getSystemTime()方法)。

  • service方法实现中只实现一些简单的业务逻辑(如isExistedUsername方法的实现),若有复杂的业务逻辑,则在service.business包中创建具体 的BO类(Business Object),转给BO类去处理。如下图把当前的业务逻辑放到BO类中去实现。

注意:由于BO类不是Spring Bean,要获取Spring Bean请使用PluginBeanProvider.java类获取。

2.2.2.3. infrastructure层实现(数据交互)

infrastructure层主要用于与各种数据交互,或提供一些基础的服务能力(如加密/解密)。

在接口DemoV2CustomRepository.java中定义了统计用户数量的方法,如下图:

在Hibernate实现类DemoV2CustomRepositoryHibernate.java中提供了具体的查询实现(该类是一个Spring Bean,类名上增加了注解 @Repository), 如下图:

  • 该类继承了抽象类AbstractRepositoryHibernate.java,此类中提供了各种Hibernate的常用操作方法(如 saveOrUpdate),可自行查看,其中 最常用的方法是session()用于获取一个Session实例,如此处查询就用了。

  • Repository中的数据库操作不能使用HQL,只能使用SQL语句进行操作。

提示:如何能知道IDP平台中有哪些表(table),请在项目交付中联系项目经理或交付工程师,通过商务途径获取。

2.3. 测试API

假设部署IDP的访问地址为:https://{IDaaS_server}

1.按照应用模板插件中的’上传插件’与’使用插件’两部分的内容,在IDP平台中创建应用实例。

2.测试公开API /public/api/application/plugin_v2_demo/system_time。使用postman等工具直接访问完整的API即可。

完整的API路径为:https://{IDaaS_server}/public/api/application/plugin_v2_demo/system_time。

3.测试受API access_token保护的API /api/application/plugin_v2_demo/is_existed_username

  • 获取 access_token。先开启应用的API功能,复制API Key与 API Secret,如下图:

然后通过请求oauth/token URL获取 access_token,参与说明详见下图:

参数说明:

- client_id,API Key
- client_secret,API Secret
- grant_type,固定值 client_credentials
- scope,固定值 read
  • 使用postman等工具调用API,如下图:

注意:token需要放在Header中,key为 Authorization,value为 Bearer {token}

3. 注意事项

  • 若调用需要access_token 的API不带token,会出现如下错误。

  • API开发后一定要测试通过,并输出交付文档。

4. 常见QA

4.1. 如何增加自定义的数据库表?

在插件中可以支持自定义的数据库表, SQL必须要符合 阿里巴巴Java开发手册中的规范。

具体增加的示例可查看应用模板插件中的’持久化’部分的内容。

4.2. 对自定义API的性能有哪些要求?

  1. 禁用查询返回所有数据,都通过分页返回具体的数据(每页最多不超过100条数据)。

  2. 若有批量操作API,则每次批量最多处理100条数据。

4.3. 对自定义API有哪些安全要求或限制?

  1. 自定义API的插件仅限于专有部署环境(或客户私有部署环境)使用,禁止放在公网上公开使用。

  2. API实现遵守’最小化使用’原则,能满足具体的定制需求即可。

  3. 一定要注意自定义API的项目数据安全问题(每个项目必须走一遍’对外数据披露’流程)。