UNPKG

@inventorjs/api-service

Version:
117 lines (98 loc) 3.73 kB
# api-service ## 特性 - 内部请求使用 [Axios](https://github.com/axios/axios) 实现跨平台请求能力 - 支持 Axios 的所有能力,并进行一定程度的扩展如(retry, race condition, reqId, logger, urlParams 等) - 将 Axios 超时转化为 AbortSignal 处理(axios 内置 timeout 无法处理 node 端连接超时) - 支持预定义拦截器,可以将拦截器作为配置信息初始化 - 采用规范化装饰器 (@Service, @Api) 定义服务与 API,便于对 API 进行统一管理 - 自动将 API 定义转化为服务调用,调用方式与本地函数调用方式相同 ## 安装 ``` pnpm add @inventorjs/api-service@latest ``` ## 接口说明 ### Entities - ApiService: 核心服务类,用于初始化服务,和提供核心接口调用功能,对服务进行初始化 - init: 初始化所有服务,创建内部请求实例,全局调用一次 - @Service: Service 装饰器,用于提供服务定义信息 - @Api: Api 装饰器,用于提供 api 定义信息 ### Types ``` // 提供服务定义配置,可通过 init/@Service/@Api 三个接口传入,并自动进行合并 // 配置合并顺序 defaults <- init <- @Service <- @Api <- apiCall interface ApiConfig<D = unknown> extends AxiosRequestConfig<D> { // ... // 支持所有其他 Axios 配置参数 // 扩展配置 $ext?: { observe?: 'body' | 'response' // 选择获取响应对象/响应体(response.data),默认 response rcChannel?: string // race condition channel, 用于解决请求竞态问题,返回最新的数据 retry?: number // 失败重试次数,默认不重试,默认重试延时:Math.min(2 ** retryCount, 30) * 1000 reqIdHeaderName?: string // reqId http header,用于再请求头中注入 reqId,默认不住入 genReqId?: { (config: ApiConfig): string } // reqId 生成算法,默认使用 uuid 算法 logger?: boolean | LoggerConfig // 日志配置,默认开启(浏览器端默认关闭) urlParams?: Record<string, number | string> // url 参数对象,支持如 "/:id" 的url,并进行自动替换 requestInterceptors?: (typeof RequestInterceptor)[] // 请求拦截器, 注:拦截器只能在 @Service 层级以上配置 responseInterceptors?: (typeof ResponseInterceptor)[] // 响应拦截器 注:拦截器只能在 @Service 层级以上配置 } } // ApiService 定义 declare class ApiService { private static rcChannelMap private static inited static init({ services, config: rootConfig, }: { services: ClassType<ApiService>[] config?: ApiConfig }): Promise<void> static apiCall<R, D = unknown>( this: ClassType<ApiService>, data?: D, config?: ApiConfig, ): Promise<unknown> } // @Service 定义 declare function Service( serviceConfig: ApiConfig, ): (Cls: ClassType<ApiService>) => void // @Api 定义 declare function Api( apiConfig: ApiConfig, ): ( Cls: ClassType<ApiService>, propertyKey: string, propertyDescriptor: PropertyDescriptor, ) => void ``` ## 示例 ``` // user.service.ts import { Service, Api, ApiService, type ApiConfig } from '@inventorjs/api-service' import { UserService } from './user.service' @Service({ baseURL: 'https://run.mocky.io/v3', }) export class UserService extends ApiService { @Api({ url: '/d7389eca-12e9-4e0e-b55e-4704fe7cbfc4' }) static getData(data?: void, config?: ApiConfig) { return this.apiCall<Record<string, unknown>>(data, config) } } // index.ts 初始化 ApiService ApiService.init({ services: [UserService], config: { $ext: { reqIdHeaderName: 'x-req-id', observe: 'body', retry: 3, }, }, }) // call api somewhere UserService.getData().then((d) => { console.log(d) }) ```