HarmonyOS NEXT:面向对象式的网络请求,我发布了第一个鸿蒙三方库

引言

为处理大量重复的代码逻辑,基于 http 封装的一套面向对象式的网络请求库 ,支持将请求返回的数据直接转换成指定类型的对象。本篇记录封装前后的使用对比,以及在鸿蒙ohpm发布三方库的操作记录。

官网的 http 案例

如下代码,是官方给出的请求案例:

ts 复制代码
// 引入包名
import http from '@ohos.net.http';

// 每一个httpRequest对应一个HTTP请求任务,不可复用
let httpRequest = http.createHttp();
// 用于订阅HTTP响应头,此接口会比request请求先返回。可以根据业务需要订阅此消息
// 从API 8开始,使用on('headersReceive', Callback)替代on('headerReceive', AsyncCallback)。 8+
httpRequest.on('headersReceive', (header) => {
    console.info('header: ' + JSON.stringify(header));
});
httpRequest.request(
    // 填写HTTP请求的URL地址,可以带参数也可以不带参数。URL地址需要开发者自定义。请求的参数可以在extraData中指定
    "EXAMPLE_URL",
    {
        method: http.RequestMethod.POST, // 可选,默认为http.RequestMethod.GET
        // 开发者根据自身业务需要添加header字段
        header: {
            'Content-Type': 'application/json'
        },
        // 当使用POST请求时此字段用于传递内容
        extraData: {
            "data": "data to send",
        },
        expectDataType: http.HttpDataType.STRING, // 可选,指定返回数据的类型
        usingCache: true, // 可选,默认为true
        priority: 1, // 可选,默认为1
        connectTimeout: 60000, // 可选,默认为60000ms
        readTimeout: 60000, // 可选,默认为60000ms
        usingProtocol: http.HttpProtocol.HTTP1_1, // 可选,协议类型默认值由系统自动指定
    }, (err, data) => {
        if (!err) {
            // data.result为HTTP响应内容,可根据业务需要进行解析
            console.info('Result:' + JSON.stringify(data.result));
            console.info('code:' + JSON.stringify(data.responseCode));
            // data.header为HTTP响应头,可根据业务需要进行解析
            console.info('header:' + JSON.stringify(data.header));
            console.info('cookies:' + JSON.stringify(data.cookies)); // 8+
            // 取消订阅HTTP响应头事件
            httpRequest.off('headersReceive');
            // 当该请求使用完毕时,调用destroy方法主动销毁
            httpRequest.destroy();
        } else {
            console.info('error:' + JSON.stringify(err));
            // 取消订阅HTTP响应头事件
            httpRequest.off('headersReceive');
            // 当该请求使用完毕时,调用destroy方法主动销毁。
            httpRequest.destroy();
        }
    }
);

可以看到,上述请求的代码量庞大,在实际开发中,我们需要将公共的部分进行抽取封装,将可变的参数暴露到上层进行动态填充或者重写,达到简化请求代码的目标。

fast_http,一个简易面向对象式的网络库

1. 安装

ts 复制代码
ohpm install @rex/fast_https_request

2. 导入引用

ts 复制代码
import { http } from '@kit.NetworkKit'
import { HttpRequest } from '@rex/fast_https_request/Index';

3. 定义通用数据模型

首先,我们定义一个常规返回数据模型,比如这样的JSON结构:

ts 复制代码
{
    'code': 100
    'data': {
        // 里面是具体的业务模型
    }
}

对应的模型我们定义如下:

ts 复制代码
/// 接口返回结果通用模型, 泛型T为具体的业务模型对象
interface CommonResponseModel<T> {
  code: number
  data: T
}

4. 定义业务数据模型

定义具体的业务数据模型,也就是上述 CommponResponseModel 里的 T 泛型,例如这样

ts 复制代码
/// 具体的业务模型
class ResponseModel {
  artistsname: string
  name: string
  picurl: string
  url: string

  constructor(
    artistsname: string,
    name: string, picurl:
    string, url: string
  ) {
    this.artistsname = artistsname
    this.name = name
    this.picurl = picurl
    this.url = url
  }
}

5. 创建网络请求

声明网络请求,指定将返回结果直接转换成上面的业务模型,我们这么做:

  • 如果是GET请求,这么写
ts 复制代码
// HttpRequest<T> 将response的返回数据直接转成指定的泛型
class GetRequest extends HttpRequest<CommonResponseModel<ResponseModel>> {
  // 重写请求类型,默认是 POST
  public method: http.RequestMethod = http.RequestMethod.GET;
  // 重写域名domain
  public domain: string = 'https://api.uomg.com';
  // 重写请求路径
  public path: string = '/api/rand.music';
  // GET 传参赋值
  public getQuery: Record<string, string> = {
    'sort': '热歌榜',
    'format': 'json',
  }
}
  • 如果是POST请求,这么写
ts 复制代码
class PostRequest extends HttpRequest<CommonResponseModel<ResponseModel>> {
  // 重写请求类型,默认是 POST
  public method: http.RequestMethod = http.RequestMethod.POST;
  // 重写域名domain
  public domain: string = 'https://api.uomg.com';
  // 重写请求路径
  public path: string = '/api/comments.163';
  // POST 传参赋值
  public postBody: Record<string, string> = {
    'format': 'json',
  }
}

6. 发送网络请求

ts 复制代码
try {
      const response : CommonResponseModel<ResponseModel> = await new GetRequest().execute()
      let responseTxt = JSON.stringify(response);
      console.log(`response == ${responseTxt}`)
    } catch (e) {
      let errorMessage = JSON.stringify(e);
      console.log(`error == ${errorMessage}`)
    }

使用上面声明的请求 new GetRequest().excute() 或者 new PostRequest().excute() 获取到的结果为 CommonResponseModel<ResponseModel> 对象

ts 复制代码
let data : ResponseModel = await new GetRequest().execute().data   

这样就获取到了我们的业务模型对象

7. 如何打印网络日志

在继承 HttpRequest 时选择重写内部三方方法,可用于分别打印 request、response、httpError

ts 复制代码
class PostRequest extends HttpRequest<T> {
  ....省略具体的请求
  
  // 重写该方法打印 request
  protected onRequestChain(request: BaseRequestOption): void {
    console.log(`fast_http_request >>> url : ${this.requestUrl()}`)
    if (request.postBody != null){
      console.log(`fast_http_request >>> POST Parmas : ${JSON.stringify(request.postBody)}`)
    }
  }

  // 重写该方法打印 response
  protected onResponseChain(response: HttpResponse): void {
    console.log(`fast_http_request >>> response : ${JSON.stringify(response)}`)
  }

  // 重写该方法打印 http error
  protected onErrorChain(error: Error): void {
    console.log(`fast_http_request >>> error : ${JSON.stringify(error)}`)
  }
}

8. 如何在工程中,统一管理,进行复用

我们可以按照域名定义一个通用的 CommonRequest,例如:

ts 复制代码
class CommonRequest<T> extends HttpRequest<CommonResponseModel<T>> {
  // 重写域名domain
  public domain: string = 'https://api.uomg.com';
  
  ///这里自己把log加上,统一打印请求日志
}

遇到具体的业务时

假设我们业务接口返回的的数据,定义模型名称为 BusinessModel

ts 复制代码
class BusinessModel {
    /// 具体的业务字段
}

所有的业务请求,我们可以通过继承 CommonRequest,创建具体的业务请求,指定泛型即可

ts 复制代码
class BusinessRequest extends CommonRequest<BusinessModel> {
    // Model 是请求参数,这里我定义为 Record 类型,按照自己的需要也可以定义为其他
    constructor(requestParams: Record<string, Object>){
        this.postBody = requestParams;
    }
    
    // 重写请求路径
  public path: string = '具体的url';
}

如上便完成了一个业务请求的封装, 通过 new 即可使用

ts 复制代码
let requestParams = {
    'pageIndex': '1',
    'keywords': 'rex',
}

let request = new BusinessRequest(requestParams);

request.excute().then((data)=>{
    // 这里获取的 data 类型为 CommonResponseModel<BusinessModel>
})

聊一下怎么发布到鸿蒙三方库市场

1. 创建组织

先到 OpenHarmony三方库中心仓 上面注册个账号,到 个人中心 ->组织管理 中,申请一个组织。这个组织名字以后要用到,因为普通三方作者,是不能使用 ohos 前缀的。

比如我注册的是组织名为 rex,组件为 fast_https_request。那么组件最终的名字就是 @rex/fast_https_request

最后用户可以通过 ohpm install @candies/fast_https_request,来安装使用组件。

2. 创建项目(选择静态库)

创建项目,选择静态库(Static Libray)

对应的 oh_package.json5 文件里配置的是组件的相关信息

其他字段,请查看 OpenHarmony三方库中心仓

3. 发布

在准备发布之前,请先阅读 贡献三方库 里面内容。

这里简单说一下组件内需要包含的必要的文件:

    1. 配置 oh-package.json5 文件,是对当前三方库的元数据描述
    1. 创建 README 文件,为了帮助其他人在 ohpm 上找到您的三方库
    1. 创建 CHANGELOG 文件,描述版本及更新内容
    1. 添加 LICENSE 文件,开源协议

然后将你的组件编译生成静态包 .har

生成完毕后执行命令行进行发布:

ohpm publish xxx.har

(xxx.har 为上传包的本地路径)。上传成功之后,你就可以看到你的个人中心里面的消息和状态了,耐心等待审核。

PS: 组织名申请会比较耗时

已开源,附上源码及Example

相关推荐
张帅涛_6663 小时前
HarmonyOS ArkUI 构建布局
华为·harmonyos
冯志浩13 小时前
Harmony NEXT:如何给数据库添加自定义分词
harmonyos·掘金·金石计划
爱桥代码的程序媛15 小时前
鸿蒙OpenHarmony【轻量系统芯片移植案例】标准系统方案之瑞芯微RK3568移植案例
嵌入式硬件·harmonyos·鸿蒙·鸿蒙系统·移植·openharmony·鸿蒙开发
AORO_BEIDOU15 小时前
防爆手机+鸿蒙系统,遨游通讯筑牢工业安全基石
5g·安全·智能手机·信息与通信·harmonyos
小强在此1 天前
【基于开源鸿蒙(OpenHarmony)的智慧农业综合应用系统】
华为·开源·团队开发·智慧农业·harmonyos·开源鸿蒙
PlumCarefree1 天前
基于鸿蒙API10的RTSP播放器(四:沉浸式播放窗口)
华为·harmonyos
中关村科金2 天前
中关村科金推出得助音视频鸿蒙SDK,助力金融业务系统鸿蒙化提速
华为·音视频·harmonyos
小强在此2 天前
基于OpenHarmony(开源鸿蒙)的智慧医疗综合应用系统
华为·开源·团队开发·健康医疗·harmonyos·开源鸿蒙
奔跑的露西ly2 天前
【鸿蒙 HarmonyOS NEXT】popup弹窗
华为·harmonyos