网络请求
介绍
网络请求模块负责统一管理接口调用与拦截器配置,对外只暴露 DataSource。业务层通过 data 模块的 Repository 获取数据,不直接依赖网络模块。
模块结构
- NetworkClient:统一管理 Axios 实例与基础配置。
- interceptors:请求与响应拦截器统一注册。
- datasource:按业务模块拆分的网络数据源接口与实现。
NetworkClient
文件位置:core/network/src/main/ets/NetworkClient.ets
- 统一管理 Axios 实例与基础配置(baseUrl、timeout、headers)。
- 通过
NetworkClient.http对外提供请求入口。 - Axios 文档:https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Faxios
拦截器
拦截器分两层:全局拦截器注册 + 日志拦截器。日志拦截器会把请求与响应打印到控制台,方便排查问题。
全局拦截器注册
文件位置:core/network/src/main/ets/interceptors/AppInterceptors.ets
登录成功后会把 Token 存到本地,后续请求会自动从本地读取并写入请求头。如需调整请求头或拦截逻辑,直接修改该文件即可。
日志拦截器
文件位置:core/network/src/main/ets/interceptors/LogInterceptor.ets
日志拦截器会把请求参数与响应结果打印到控制台,方便快速定位问题。
数据源接口与实现
下面以商品模块为例,展示 DataSource 的标准写法。
数据源接口
文件位置:core/network/src/main/ets/datasource/goods/GoodsNetworkDataSource.ets
import {
Goods, NetworkPageData, NetworkResponse, GoodsSearchRequest,
} from "model";
/**
* @file 商品相关数据源接口
*/
export interface GoodsNetworkDataSource {
/**
* 分页查询商品
* @param params 商品搜索请求参数
* @returns 商品分页数据响应
*/
getGoodsPage(params: GoodsSearchRequest): Promise<NetworkResponse<NetworkPageData<Goods>>>;
/**
* 获取商品信息
* @param id 商品ID
* @returns 商品信息响应
*/
getGoodsInfo(id: string): Promise<NetworkResponse<Goods>>;
}数据源实现
文件位置:core/network/src/main/ets/datasource/goods/GoodsNetworkDataSourceImpl.ets
import { AxiosResponse } from "@ohos/axios";
import { NetworkClient } from "../../NetworkClient";
import {
Goods, GoodsSearchRequest, NetworkPageData, NetworkResponse
} from "model";
import { GoodsNetworkDataSource } from "./GoodsNetworkDataSource";
/**
* @file 商品相关数据源实现类
*/
export class GoodsNetworkDataSourceImpl implements GoodsNetworkDataSource {
/**
* 分页查询商品
* @param params 商品搜索请求参数
* @returns 商品分页数据响应
*/
async getGoodsPage(params: GoodsSearchRequest): Promise<NetworkResponse<NetworkPageData<Goods>>> {
const resp: AxiosResponse<NetworkResponse<NetworkPageData<Goods>>> =
await NetworkClient.http.post("goods/info/page", params);
return resp.data;
}
/**
* 获取商品信息
* @param id 商品ID
* @returns 商品信息响应
*/
async getGoodsInfo(id: string): Promise<NetworkResponse<Goods>> {
const resp: AxiosResponse<NetworkResponse<Goods>> =
await NetworkClient.http.get("goods/info/info", { params: { id } });
return resp.data;
}
}仓库示例
文件位置:core/data/src/main/ets/repository/GoodsRepository.ets
import { GoodsNetworkDataSource, GoodsNetworkDataSourceImpl } from "network";
import {
Goods, GoodsSearchRequest, NetworkPageData, NetworkResponse
} from "model";
/**
* @file 商品相关仓库类,封装商品模块请求
*/
export class GoodsRepository {
/**
* 商品网络数据源
*/
private networkDataSource: GoodsNetworkDataSource;
/**
* 构造函数
* @param networkDataSource 可选的商品网络数据源实例
*/
constructor(networkDataSource?: GoodsNetworkDataSource) {
this.networkDataSource = networkDataSource ?? new GoodsNetworkDataSourceImpl();
}
/**
* 分页查询商品
* @param params 商品搜索请求参数
* @returns 商品分页数据
*/
async getGoodsPage(params: GoodsSearchRequest): Promise<NetworkResponse<NetworkPageData<Goods>>> {
return this.networkDataSource.getGoodsPage(params);
}
/**
* 获取商品信息
* @param id 商品ID
* @returns 商品详情
*/
async getGoodsInfo(id: string): Promise<NetworkResponse<Goods>> {
return this.networkDataSource.getGoodsInfo(id);
}
}ViewModel 使用示例
文件位置:feature/demo/src/main/ets/viewmodel/NetworkRequestViewModel.ets
网络请求通常配合 result 模块的 RequestHelper 使用,用来统一处理加载状态与回调。
下面截取 GET 和 POST 的常用写法,展示如何通过仓库发起请求。
import { BaseViewModel } from "base";
import { GoodsRepository } from "data";
import { Goods, GoodsSearchRequest, NetworkPageData } from "model";
import { RequestHelper } from "result";
import { ToastUtils } from "util";
/**
* @file 通用网络请求示例页 ViewModel
*/
@ObservedV2
export default class NetworkRequestViewModel extends BaseViewModel {
/**
* 商品仓库
*/
private repository: GoodsRepository = new GoodsRepository();
/**
* 发起 GET 请求(商品详情)
*/
requestGoodsDetail() {
RequestHelper.repository<Goods>(this.repository.getGoodsInfo("1"))
.execute()
.then((data: Goods): void => {
// 处理 GET 请求成功逻辑
});
}
/**
* 发起 POST 请求(商品列表)
*/
requestGoodsList() {
const params: GoodsSearchRequest = new GoodsSearchRequest();
params.page = 1;
params.size = 20;
RequestHelper.repository<NetworkPageData<Goods>>(this.repository.getGoodsPage(params))
.execute()
.then((): void => {
// 处理 POST 请求成功逻辑
});
}
}与数据层的关系
- 网络模块不直接给业务层使用。
- 业务通过 data 模块的 Repository 访问网络数据。
- Repository 统一对外提供业务语义方法,保持依赖收敛。
如何新增接口
- 在
core/network/src/main/ets/datasource/下新增业务文件夹。 - 编写数据源接口与实现,封装接口地址与参数。
- 在 data 层新增 Repository,对外提供语义化方法。
- 在对应
Index.ets补充导出,保证上层统一引入。