ABP开发框架前后端开发系列---(10)Web API调用类的简化处理

ABP开发框架前后端开发系列---(10)Web API调用类的简化处理,第1张

概述在较早期的随笔《ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用》已经介绍了Web API调用类的封装处理,虽然这些调用类我们可以使用代码生成工具快速生成,不过自定义接口,还是需要我们对这些接口进行实现,以便发起对Web API的调用,并获得相应的数据返回。本篇随笔介绍使用API调用类的封装类,进行函数的抽象,根据方法名称的推断,构建URL或者WebClie

在较早期的随笔《ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用》已经介绍了Web API调用类的封装处理,虽然这些调用类我们可以使用代码生成工具快速生成,不过自定义接口,还是需要我们对这些接口进行实现,以便发起对Web API的调用,并获得相应的数据返回。本篇随笔介绍使用API调用类的封装类,进行函数的抽象,根据方法名称的推断,构建URL或者WebClIEnt的请求类型,从而实现所有API调用函数的简化处理。

1、ABP框架服务端和客户端的处理

ABP框架的架构图示,如下图所示(以字典模块为例说明)

针对Web API接口调用的封装,为了适应客户端快速调用的目的,这个封装作为一个独立的封装层,以方便各个模块之间进行共同调用。

而ABP的Web API调用类则需要对Web API接口调用进行封装,如下所示。

如对于字典模块的API封装类,它们继承一个相同的基类,然后实现特殊的自定义接口即可,这样可以减少常规的Create、Get、GetAll、Update、Delete等 *** 作的代码,这些全部由调用基类进行处理,而只需要实现自定义的接口调用即可。

 

2、Web API调用类的简化处理

我们对于常规的Web API调用接口处理,如下代码所示。

        public async virtual Task<AuthenticateResult> Authenticate(string username,string password)        {            var url = string.Format("{0}/API/TokenAuth/Authenticate",ServerRootAddress);            var input = new            {                UsernameOrEmailAddress = username,Password = password            };            var result = await apiclient.PostAsync<AuthenticateResult>(url,input);            return result;        }

这种方法的处理,就需要自己拼接URL地址,以及传递相关的参数,一般情况下,我们的Web API Caller层类的函数和Web API控制器的方法是一一对应的,因此方法名称可以通过对当前接口名称的推断进行获得,如下所示。

        public async Task<bool> ChangePassword(ChangePasswordDto input)        {            AddRequestheaders();//加入认证的token头信息            string url = GetActionUrl(MethodBase.GetCurrentMethod());//获取访问API的地址(未包含参数)            return await apiclient.PostAsync<bool>(url,input);        }

函数AddRequestheaders 通过在调用前增加对应的Accesstoken信息,然后URL通过当前方法的推断即可构建一个完整的URL,但是这个也仅仅是针对POST的方法,因为ABP框架根据方法的名称前缀的不同,而采用POST、GET、Delete、PUT等不同的http处理 *** 作。

如GET方法,则是需要使用GET请求

        public async Task<List<RoleDto>> GetRolesByUser(EntityDto<long> input)        {            AddRequestheaders();//加入认证的token头信息            string url = GetActionUrl(MethodBase.GetCurrentMethod());//获取访问API的地址(未包含参数)            url = GetUrlParam(input,url);            var result = await apiclient.GetAsync<List<RoleDto>>(url);            return result;        }

而对于删除方法,则使用下面的DELETE请求,DELETE 和PUT *** 作,需要把参数串联成GET的URL形式,类似 url += string.Format("?ID={0}",ID); 这样方式

        public virtual async Task Delete(TDeleteinput input)        {            AddRequestheaders();//加入认证的token头信息            string url = GetActionUrl(MethodBase.GetCurrentMethod());//获取访问API的地址(未包含参数)            url += GetUrlParam(input,url);            var result = await apiclient.DeleteAsync(url);            return result;        }

对于更新的 *** 作,使用了PUT方法

        public async virtual Task<TEntityDto> Update(TUpdateinput input)        {            AddRequestheaders();//加入认证的token头信息            string url = GetActionUrl(MethodBase.GetCurrentMethod());//获取访问API的地址(未包含参数)            var result = await apiclient.PutAsync<TEntityDto>(url,input,null);            return result;        }

上面这些方法,我们根据规律,其实可以进一步进行简化,因为这些 *** 作大多数类似的。

首先我们看到变化的地方,就是根据方法的前缀采用GET、POST、DELETE、PUT方法,还有就是URL串联字符串的不同,对于GET、Delete方法,参数使用的是组成URL方式,参数使用的是JsON提交内容方式。

根据这些变化,我们在基类提炼一个统一的处理方法DoActionAsync 来处理这些不同的 *** 作。

        /// <summary>        /// 根据方法名称自动执行GET/POST/PUT/DELETE请求方法        /// </summary>        /// <param name="method"></param>        /// <param name="input"></param>        protected virtual async Task DoActionAsync(MethodBase method,object input = null)        {            await DoActionAsync<object>(method,input);        }
        /// <summary>        /// 根据方法名称自动执行GET/POST/PUT/DELETE请求方法        /// </summary>        /// <param name="method"></param>        /// <param name="input"></param>        protected virtual async Task<TResult> DoActionAsync<TResult>(MethodBase method,object input = null)        {            AddRequestheaders();//加入认证的token头信息            string action = getmethodname(method);            var url = string.Format("{0}/API/services/app/{1}/{2}",ServerRootAddress,Domainname,action);//获取访问API的地址(未包含参数)            var httpVerb = DynamicAPIVerbHelper.GetConventionalVerbForMethodname(action);            if(httpVerb == httpVerb.Get || httpVerb == httpVerb.Delete)            {                if (input != null)                {                    //Get和Delete的 *** 作,需要组装URL参数                    url = GetUrlParam(input,url);                }            }            int? timeout = null;            return await apiclient.DoActionAsync<TResult>(url,timeout,httpVerb.ToString().Tolower(),input);        }

这样,有了这两个函数的支持,我们可以简化很多 *** 作代码了。

例如对于Update方法,简化的代码如下所示。

        public async virtual Task<TEntityDto> Update(TUpdateinput input)        {            return await DoActionAsync<TEntityDto>(MethodBase.GetCurrentMethod(),input);        }

对于删除 *** 作,简化的代码依旧也是一行代码

        public virtual async Task Delete(TDeleteinput input)        {            await DoActionAsync(MethodBase.GetCurrentMethod(),input);        }

GET *** 作,也是一行代码

        public async virtual Task<TEntityDto> Get(TGetinput input)        {            return await DoActionAsync<TEntityDto>(MethodBase.GetCurrentMethod(),input);        }

现在你看到,所有的客户端API封装类调用,都已经非常简化,大同小异了,主要就是交给基类函数进行推断调用处理即可。

如用户 *** 作的APICaller类的代码如下所示。

这样我们再多的接口,都一行代码调用解决问题,非常简单,从此客户端封装类的实现就非常简单了,只需要注意有没有返回值即可,其他的都没有什么不同。

只需要注意的是,我们定义接口的时候,尽可能使用复杂类型对象,这样就可以根据对象属性名称和值进行构建URL或者JsON的了。

总结

以上是内存溢出为你收集整理的ABP开发框架前后端开发系列---(10)Web API调用类的简化处理全部内容,希望文章能够帮你解决ABP开发框架前后端开发系列---(10)Web API调用类的简化处理所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1066024.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存