项目中使用了dio自封装的轻量网络请求方案,但是对于新增接口的接入、Model数据结构的管理、Api接口调用等,在使用上并不太友好便捷,大大的影响了团队的开发效率。
现状
项目内当前使用的方案
底层封装
将dio相关请求封装成底层单例类,所有的请求最后都会走到该单例内部,执行网络请求,并返回result暴露了一个抽象的BaseRequest类给到应用层,所有的Api接口地址,参数,loading行为都放到具体的实现类中完成,实现类需要集成该BaseRequest类,并配置响应的接口参数。
静态调用,使用静态方法封装上述流程,返回裸result给到应用层
该方案的具体问题
每次需要新增接口的时候,应用层都需要新增一个类来继承BaseRequest,配置接口&参数。这个新增类只是为了配置接口,却引入了一个文件,不是很合理
调用人员通过方法只能拿到result裸返回数据,并不知道其具体的数据结构,需要自己处理,所以使用中出现了很多地方先判断返回码再解析的问题,出现很多 result[‘code’] == 200 这种东西,同时数据结构的解析也需要参考之前调用的地方,去copy过来,使用上并不方便便捷。
优化方向
根据上述分析,我希望每次新增接口只写一个静态方法即可,在该静态方法中去配置请求地址和参数,这样只需要引入一个方法,减少了文件引入的问题。
我是调用者,我只关注是否调用成功,成功后应该给我对应的数据结构,而不是让我去看别人的代码再copy代码来解析。
是否可以把调用成功的判断统一起来,不要每个调用接口的地方都去自己写判断,能否用一行代码处理呢。
是否有类似java的反射方案,自动使用泛型来处理裸返回数据的解析?
优化
配置优化
使用CommonRequest去实现BaseRequest,并把配置地址和参数作为构造参数传入,这样就不用每次引入一个新的文件去配置了
1 | ///通用请求类 |
响应返回优化
使用BaseResModel封装response裸数据返回,把返回的数据解析成BaseResModel,对返回的code和msg做统一处理,统一封装请求是否成功的判断,介于需要根据response构建数据,这里传入一个泛型T,response需要根据T来构建返回结构体。
dart中必须要运行时才能确认泛型的具体数据,所以类型T并不能被要求提供特定的构建方法,基于此,可以把构建方法传进来,返回结构体根据该构建方法来创建。
1 | class BaseResModel<T> { |
调用方法优化
BaseRequest已经封装了相关的接口&参数,那么可以直接为BaseRequest添加一个send方法即可
1 | extension BaseRequestExtension on BaseRequest { |
实现方案调用
下面是一个优化后的请求构建&调用的例子
1 | static Future<BaseResModel<MyAppState>> getMyAppStateState() async { |
当新增接口接入的时候,只需要添加上诉方法并根据返回数据定义好MyAppState返回结构体即可,后续其他人的调用就不再需要考虑返回数据结构,他可以直接使用该model带的数据进行处理。