# api **Repository Path**: wsvaio/api ## Basic Information - **Project Name**: api - **Description**: @wsvaio/api - **Primary Language**: TypeScript - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-03-12 - **Last Updated**: 2023-03-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 以洋葱模型运行机制对 fetch 的包装 ## 快速使用 ```typescript import { createAPI } from "@wsvaio/api"; export const { get, use } = createAPI({ baseURL: "/api", }); use("befores")(async ctx => { ctx.headers["auth"] = "..."; }); use("afters")(async ctx => { console.log(ctx.data); // { code: 0, msg: 'success', data: 'xxxx' } ctx.data = ctx.data.data; }); export const getTest = get("/user"); const data = await getTest({ query: { id: 1 } }); // get: /api/user?id=1 console.log(data); // xxxx ``` ## 中间件 ### 中间件有四种类型 1. before: 前置中间件,请求发出前调用 2. after: 后置中间件,请求发出后调用 3. error: 错误中间件,发生错误时调用 4. final: 最终中间件,最后才会调用 ### 配置中间件 1. 创建时配置 ```typescript export const api = createAPI({ befores: [async ctx => console.log("before")], }); api.use("befores")(async ctx => console.log("before")); ``` 2. 调用时配置 ```typescript const api = createAPI({ method: "get", befores: [async ctx => console.log("before")], }); // 中间件的配置不会覆盖创建时的配置,与创建时配置合并,其他配置则会覆盖,如method api.request({ method: "post", befores: [async ctx => console.log("before")] }); ``` ### 运行机制 运行机制使用了洋葱模型 ```typescript export const api = createAPI(); api.use("befores")( async ctx => { // 没有接收next参数会自动调用next console.log("before1"); }, async (ctx, next) => { // 接受了next参数需要手动调用next才能执行下一个中间件 console.log("before2 in"); await next(); // 后续中间件执行完毕后执行 console.log("before2 out"); }, async (ctx, next) => { // 接受了next参数,没有调用next,之后的中间件都不会调用 console.log("before3"); } ); ``` ## 发送请求 ```typescript const api = createAPI(); // api.request方法会直接调用,其它请求方法需要调用两次,方便配置 // 先配置再调用 const getTest = api.get("/test"); getTest({ query: { id: 1 } }); // 直接发送请求 api.request({ url: "/test", query: { id: 1 } }); // 泛型支持,P:body、query、param属性的类型提示,R:响应内容的类型 type P = { id: number }; type R = { message: string }; const postTest = api.post
("/test/:id?");
const data = await postTest({
body: { id: 1 }, // 设置请求体
param: { id: 1 }, // param会替换对应的/:key
query: { id: 1 }, // query会拼接到url后
// b、p、q等同body、param、query,优先级比它们低,b只能接受对象类型,body可以接受FormData、ArrayBuffer、Blob等复杂类型;
b: {},
p: {},
q: {},
});
```
## Context
完整的 Context 包括以下属性
```typescript
type Context = {
// fetch配置
cache?: RequestCache;
credentials?: RequestCredentials;
integrity?: string;
keepalive?: boolean;
mode?: RequestMode;
redirect?: RequestRedirect;
referrer?: string;
referrerPolicy?: ReferrerPolicy;
signal?: AbortSignal | null;
window?: null;
// 以上为fetch配置
method: "get" | "post" | "put" | "patch" | "delete" | "options" | "head" | "connect" | "trace";
headers: HeadersInit;
log: boolean; // 控制台是否打印日志
timeout: number; // 请求超时的毫秒数
url: string; // 请求地址
baseURL: string; // 请求根地址
body: Record