# http_decorators
**Repository Path**: coyamo/http_decorators
## Basic Information
- **Project Name**: http_decorators
- **Description**: 通过装饰器封装Axios网络请求的开源鸿蒙网络请求库,类似Retrofit。
- **Primary Language**: TypeScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2023-12-14
- **Last Updated**: 2024-01-30
## Categories & Tags
**Categories**: Uncategorized
**Tags**: 鸿蒙, HarmonyOS组件, 网络请求, retrofit
## README
# HttpDecorator
## 简介
HttpDecorator是一个用于开源鸿蒙(Open Harmony)的HTTP客户端库,使用Typescript编写实现。它通过将HTTP请求映射为装饰器驱动的方法,简化了网络请求的过程。开发人员可以更加方便地进行网络请求,而无需手动编写HTTP请求的代码。(内部网络请求使用Axios实现)
**开发中...**
## 开发/测试环境
| | 环境 | 版本 |
|------|-------------------|-----------------------------------------------------------------------------------|
| 开发工具 | DevEco Studio | DevEco Studio 4.0 Release
Build Version: 4.0.0.600, built on October 17, 2023 |
| 测试设备 | HUAWEI Mate 30 5G | HarmonyOS 4.0.0.116
**OpenHarmony API 9** |
## 装饰器
请求方法:`GET`, `HEAD`, `POST`, `PUT`, `DELETE`, `TRACE`,` CONNECT`, `OPTIONS`
参数标注:`Path`, `Query`,`Body`, `Header`, `HeaderMap` ,`Headers`, `QueryMap`, `Url`
| 装饰器 | 参数 | 装饰器类型 | 说明 |
|-----------|-------------------------------------------------------|-------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| GET | `path`:GET请求的路径 | 方法 | 相对路径或者完整路径,使用`{variable}`格式的字段可以映射变量,`variable`为你定义变量的名字 |
| POST | `path`:POST请求的路径 | 方法 | 同上 |
| PUT | `path`:PUT请求的路径 | 方法 | 同上 |
| HEAD | `path`:HEAD请求的路径 | 方法 | 同上 |
| DELETE | `path`:DELETE请求的路径 | 方法 | 同上 |
| TRACE | `path`:TRACE请求的路径 | 方法 | 同上 |
| CONNECT | `path`:CONNECT请求的路径 | 方法 | 同上 |
| OPTIONS | `path`:OPTIONS请求的路径 | 方法 | 同上 |
| HTTP | `value`:`{method:HttpMethod, path?:string}`自定义请求方法和路径 | 方法 | 可以自定义请求的类型
例子:
`@HTTP({ method:HttpMethod.create("custom"), path: "image/{id}" })` |
| Path | `value`:路径参数的名字 | 参数 | 用于映射参数的值到请求路径中定义的变量
例子:
`@GET("/image/{id}") example(@Path("id")id:string):Call`
执行`example('1')`
会生成路径`/image/1` |
| Query | `value`:查询参数的名字 | 参数 | 用于映射参数的值到请求路径的Query类型参数
例子:
`@GET("/image") example(@Query("id")id:string):Call`
执行`example('1')`
会生成路径`/image?id=1` |
| QueryMap | 无 | 参数 | 用于映射参数集合的值到请求路径的Query类型参数
例子:
`@GET("/image") example(@QueryMap params:object):Call`
执行`example({id:1,tag:"hello"})`
会生成路径`/image?id=1&tag=hello` |
| Header | `value`:请求头参数的名字 | 参数 | 用于映射参数的值到请求的header |
| HeaderMap | 无 | 参数 | 用于映射键值对对象参数的值到请求的header |
| Headers | `value`:header字符串数组 | 方法 | 用于标注请求的header
例子:
`@Headers(["header:hello"])` |
| Body | 无 | 参数 | 用标注参数值为请求体 |
| Url | `value`:请求的baseUrl | 参数 | 用于单独指定当前请求的base url |
## 拦截器
`HttpDecorator`单独实现了一个简易的拦截器,而不是使用`axios`提供的拦截器,且优先级高于`axios`实现的拦截器。
创建一个拦截器需要实现`Interceptor`接口。
```typescript
import { Interceptor, Response } from '@coyamo/http_decorators'
export class TestInterceptor implements Interceptor{
async intercept(chain: Interceptor.Chain): Promise {
const request = chain.getRequest()
//这里做拦截的操作
request.headers.set("Auth", "xxxxxxxxxxx")
return chain.proceed(request)
}
}
```
在创建的`HttpDecorator`实例中添加
```typescript
const httpDecorator = new HttpDecorator.Builder()
.addInterceptor(new TestInterceptor())
.addInterceptor(new HttpLoggingInterceptor())
.setAxios(axios.create({ baseURL: "https://cn.bing.com", responseType: "string" }))
.build()
```
此外,内置了一个`HttpLoggingInterceptor`拦截器用于输出请求信息。
## 简易的用法
1、创建接口类
```typescript
export class TestApiService {
@POST("/{pathVar}/{pathVar}")
@Headers(["Headers1:Hello", "Headers2:Hello,world"])
getData2(
@Url url: string,
@Path("pathVar") path: string,
@Query("queryVar") query: string,
@Body body: object,
@Header("header") header:string,
@HeaderMap headers:object,
@QueryMap queryMap:object
): Call {
throw Error()
}
}
```
2、使用
使用默认实例创建
```typescript
const api = HttpDecorator.getDefault().create(TestApiService)
```
使用自定义实例创建
```typescript
const httpDecorator = new HttpDecorator.Builder()
.setAxios(axios.create())
.build()
const api = httpDecorator.create(TestApiService)
```
调用
```typescript
const resp = api.getData2(
"http://192.168.42.38:8080",
"hello",
"world",
{ hello: "world!" },
"headerValue",
{headerMap1:"headerValue1",headerMap2:"headerValue2"},
{queryMap1:"queryMapValue1",queryMap2:"queryMapValue2"}
).execute()
resp.then((res: AxiosResponse) => {
this.message = res ? JSON.stringify(res.data) : '';
}).catch((err: AxiosError) => {
this.message = err.message;
})
```