将API接口做成统一入口的方案分享原创
金蝶云社区-范老师加油
范老师加油
7人赞赏了该文章 3,009次浏览 未经作者许可,禁止转载编辑于2023年01月13日 10:31:02
summary-icon摘要由AI智能服务提供

本文介绍了如何通过创建一个统一入口接口来适配旧系统需求,使得苍穹平台的多个功能接口能够通过不同参数调用。具体实现包括构造测试单据和接口、编写Controller插件来定义统一接口的行为,根据传入参数分发到不同功能接口。最后展示了统一入口前后的效果对比,验证了方法的可行性。此外,还提供了开发环境版本和参考资料信息。

   

关键词:开放平台,接口api二开

一、需求

       开放平台的接口都是一个url对应着一个功能,现客户为了适配旧系统的需求,需要把苍穹的接口包装成一个统一入口,通过接口参数的不同来分发到具体功能的接口。


二、思路与方案

      在这里我们可以创建一个自定义接口当作总入口,在这里根据参数apiName的不同来分发各功能接口。我们会以三个接口为例,1条单据新增的接口,1条单据查询的接口,1条自定义的接口,这3个接口的url是不一样的,而我们在统一入口里面可以通过入口参数不一样, 来分发到具体实现的接口。这样做还有一个好处就是可以把通用的功能抽取到分发类中。


三、实现过程

1  构造测试单据

在这里构造一个简单的单据,元数据在附件中

    image.png

     

2  构造测试接口

接口1 配置保存接口(请求地址:/v2/bidt/bidt_yanzheng/bidt_api_bill/saveApibill)

这里简单的只配置了三个参数字段

image.png

   接口2 配置查询接口(请求地址:/v2/bidt/bidt_yanzheng/bidt_api_bill/queryApiBill)

image.png

接口3 自定义接口:(请求地址:/v2/bidt/bidt_yanzheng/auditStatus)

插件代码:

import java.io.Serializable;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.openapi.common.custom.annotation.ApiController;
import kd.bos.openapi.common.custom.annotation.ApiModel;
import kd.bos.openapi.common.custom.annotation.ApiParam;
import kd.bos.openapi.common.custom.annotation.ApiPostMapping;
import kd.bos.openapi.common.result.CustomApiResult;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;

@ApiController(value="changeApiStatus",desc="测试")
public class AuditApiController {
	@ApiPostMapping(value="auditStatus")
	public CustomApiResult<Object> auditApiBill(@ApiParam(value = "审核单据") AuditApiReqModel data) { 
		
		QFilter filter = new QFilter("billno",QCP.equals,data.getBillno());
		DynamicObject apiBill=BusinessDataServiceHelper.loadSingle("bidt_api_bill", "billno,billstatus,bidt_sourcesys",new QFilter[] {filter});
		
		apiBill.set("billstatus",data.getStatus());
		SaveServiceHelper.saveOperate("bidt_api_bill",new DynamicObject[] {apiBill});
		return CustomApiResult.success("处理成功");
	}
}
@ApiModel
class AuditApiReqModel implements Serializable{
	@ApiParam("billno")
	private String billno;
	@ApiParam("status")
	private String status;
	public String getBillno() {
		return billno;
	}
	public void setBillno(String billno) {
		this.billno = billno;
	}
	public String getStatus() {
		return status;
	}
	public void setStatus(String status) {
		this.status = status;
	}
}

通过controller插件同步到自定义api上

image.png


3  配置一个统一入口接口


  API的controller插件如下:

在这里插件里面定义了如何根据apiName的不同跳转到不同的具体业务接口

import java.util.HashMap;
import java.util.Map;
import javax.validation.Valid;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import kd.bos.openapi.common.custom.annotation.ApiController;
import kd.bos.openapi.common.custom.annotation.ApiParam;
import kd.bos.openapi.common.custom.annotation.ApiPostMapping;
import kd.bos.openapi.common.result.CustomApiResult;
import kd.bos.openapi.common.result.OpenApiResult;
import kd.bos.openapi.common.util.OpenApiSdkUtil;

@ApiController(value="CommonBill",desc="统一url入口")
public class CommonURLApiController {
	//存放实际地址和接口入口的
	static HashMap<String,String> apiObjectMap=new HashMap();
	static{
		//这里简单的放在jvm里面维护,也可以设置成一个基础资料来维护
		apiObjectMap.put("auditApiBill", "/v2/bidt/bidt_yanzheng/auditStatus");
		apiObjectMap.put("saveApiBill","/v2/bidt/bidt_yanzheng/bidt_api_bill/saveApibill");
		apiObjectMap.put("queryApiBill", "/v2/bidt/bidt_yanzheng/bidt_api_bill/queryApiBill");
	}
	@ApiPostMapping(value="commonURLApiHandler")
	public CustomApiResult<Object> commonApiHandler(@Valid  @ApiParam("入口参数") CommonURLApiReqModel reqModel) { 
		
		String apiUrl =  apiObjectMap.get(reqModel.getApiName());
		if(apiUrl==null) {
			return CustomApiResult.fail("800", "当前接口未找到对应的接口地址!");
		}
		
		Map<String, Object> requestData = new HashMap<>();
		String reqdata=reqModel.getData();
		JSONObject requestDataJson;
		OpenApiResult   result;
		try {
			if(reqModel.getApiName().startsWith("query")) {//查询和非查询的接口传参不一样
				requestDataJson=(JSONObject) JSON.parse(reqdata) ;
				result = OpenApiSdkUtil.query(apiUrl,requestDataJson, reqModel.getPageSize(),reqModel.getPageNo());
			}else {
				reqdata="{\"data\":"+ reqdata+"}";
				requestDataJson=(JSONObject) JSON.parse(reqdata) ;
				result = OpenApiSdkUtil.invoke(apiUrl, requestDataJson, new HashMap<>());
			}
			CustomApiResult finalResult =new CustomApiResult();
			finalResult.setData(result.getData());
			finalResult.setErrorCode(result.getErrorCode());
			finalResult.setMessage(result.getMessage());
			finalResult.setStatus(result.isStatus());
			return finalResult;
		}catch(Exception e) {
			return CustomApiResult.fail("999", "未知错误!");
		}
	}

}


根据controller导入的插件

image.png



四、效果图

1   之前的效果

在没有配置统一入口的时候,每个接口的url都是不同的。

如下图 查询url 

http://localhost:8080/ierp/kapi/v2/bidt/bidt_yanzheng/bidt_api_bill/queryApiBill

image.png


保存url 

http://localhost:8080/ierp/kapi/v2/bidt/bidt_yanzheng/bidt_api_bill/saveApibill

image.png


自定义url

http://localhost:8080/ierp/kapi/v2/bidt/bidt_yanzheng/auditStatus


image.png



2  之后的效果


现在可以通过这种方式实现一个url调通其他业务接口了

这个是url:

http://localhost:8080/ierp/kapi/v2/bidt/bidt_yanzheng/commonURLApiHandler

这个是保存单据的接口,是通过统一接口转发过去的,在响应消息里面可以看到,单据已经正确生成了。

image.png



这个是查询接口。响应的返回也是刚才新增的单据数据

image.png




  这个是自定义接口的传参:

image.png

可以在下图看到代码已执行了自定义接口的逻辑

image.png




五、开发环境版本

COSMICV5.0.003.0

六、参考资料

【开发平台】指导手册

学习成长中心



图标赞 7
7人点赞
还没有人点赞,快来当第一个点赞的人吧!
图标打赏
0人打赏
还没有人打赏,快来当第一个打赏的人吧!