lither
v1.0.0
Published
a lightweight fetch request library
Downloads
22
Maintainers
Readme
English | 中文 | Installation
lither is a lightweight http request library based on vanilla fetch with Typescript
- 🌐 automatic parse restful api url parameters
- ⭐ rapid define a request api
- ⌛ timeout disconnect
- 🔤 automatic parse or serialization of JSON
- 📏 .min size less than 3K, smaller after zip
- 💡 smart type tips with Typescript
Example
export const lither = createLither({
baseURL: '/api',
timeout: 20 * 1000,
beforeRequest: (options) => {
const token = localStorage.getItem("token");
if (!token) return;
if (!options.headers) {
options.headers = new Headers();
}
options.headers.append("Authorization", token);
},
afterResponse: async (res, { resolve, reject }) => {
if (res.ok) {
if (res.responseHandler === "json") {
if (res.body.code === 0) {
resolve(res.body.data);
} else {
toast.error(res.body.err);
reject(res.body);
}
} else {
resolve(res.body ?? res);
}
} else if (res.status === 401) {
localStorage.removeItem("token");
location.href = "/login";
} else if (res.isTimeout) {
toast.error("timeout");
} else {
toast.error(res.error || res.statusText);
}
reject(res.error || res.body);
},
});
/** GET */
lither.get("/user?id=123").then((data) => console.log(data));
lither.get("/user", { query: { id: 123 } }).then((data) => console.log(data));
lither
.get("/user/:id", { params: { id: 123 } })
.then((data) => console.log(data));
/** POST */
lither
.post("/login", { body: { username: "admin", password: "123456" } })
.then((data) => console.log(data));
/**Define API */
export const login = lither
.API("/user/login")
.POST<{ username: string; password: string }, { token: string }>();
login({ username: "admin", password: "123" }).then((res) => {
localStorage.setItem("token", res.token);
});
API Reference
Request
lither.request(url[,options])
Request data can choose query
params
body
for easy specification
type LitherOptions = {
/** url search params like `api/info?name=yes` {name:"yes"} passed here*/
query?:
| Record<
string,
string | number | boolean | string[] | number[] | null | undefined
>
| URLSearchParams;
/** url rest params like `api/info/:id` {id:1} passed here*/
params?: Record<string, string | number>;
/** default 'text',if response content-type has json,then use json */
responseHandler?: "arrayBuffer" | "blob" | "formData" | "json" | "text";
/** unit ms */
timeout?: number;
/***** vanilla fetch props *****/
//body can pass json without stringified
body?: any;
signal?: AbortSignal;
method?:
| "get"
| "GET"
| "delete"
| "DELETE"
| "head"
| "HEAD"
| "options"
| "OPTIONS"
| "post"
| "POST"
| "put"
| "PUT"
| "patch"
| "PATCH"
| "purge"
| "PURGE"
| "link"
| "LINK"
| "unlink"
| "UNLINK";
mode?: "cors" | "no-cors" | "same-origin";
cache?: "default" | "no-cache" | "reload" | "force-cache" | "only-if-cached";
credentials?: "include" | "same-origin" | "omit";
headers?: Headers;
redirect?: "manual" | "follow" | "error";
referrerPolicy?:
| "no-referrer"
| "no-referrer-when-downgrade"
| "origin"
| "origin-when-cross-origin"
| "same-origin"
| "strict-origin"
| "strict-origin-when-cross-origin"
| "unsafe-url";
integrity?: string;
};
Response
type litherResponse = {
isTimeout: boolean;
error?: any;
responseHandler?: "arrayBuffer" | "blob" | "formData" | "json" | "text";
method:
| "get"
| "GET"
| "delete"
| "DELETE"
| "head"
| "HEAD"
| "options"
| "OPTIONS"
| "post"
| "POST"
| "put"
| "PUT"
| "patch"
| "PATCH"
| "purge"
| "PURGE"
| "link"
| "LINK"
| "unlink"
| "UNLINK";
/***** vanilla fetch response props *****/
/** body been handled by the option responseHandler */
body?: any;
url: string;
ok?: boolean;
headers?: Headers;
redirected?: boolean;
status?: number;
statusText?: string;
type?: string;
};
Default Options
// create a new instance
import {createLither} from 'lither'
createLither(init: LitherInit): Lither
type LitherInit = {
//**url prefix */
baseURL?: string;
//**unit ms */
timeout?: number;
/** can modify the http options before been handled*/
beforeRequest?: (options: LitherOptions) => void;
/** can modify the response after fetched and promise resolved */
afterResponse?: (response: litherResponse, { resolve, reject, }: {
resolve: (value: any) => void;
reject: (reason?: any) => void;
}) => void;
};
Features
Shortcut
lither.get(url, options);
lither.post(url, options);
lither.put(url, options);
lither.patch(url, options);
lither.delete(url, options);
lither.head(url, options);
lither.options(url, options);
Restful Url Params
url like /:key , will handle the key
lither.get("/api/user/:id", { params: { id: 1 } });
// api/user/1
lither.get("/api/:job/:year", { params: { job: "engineer", year: 5 } });
//api/engineer/5
Timeout
//** the request level timeout, will override the instance level timeout */
lither.get(url, { timeout: 1000 * 20 });
Rapid Define APIs
//can be GET POST PATCH PUT DELETE
//GET data=>query,other method data=>body
lither.API(url:string).POST<RequestType,ResponseType>()
//define an api
export const getUserInfo=lither.API('/user/:id').GET()
//then use in any where
getUserInfo({id:2})
.then(res=>console.log(res))
.catch(err=>console.log(err))
//with typescript,
export const login=lither.API('/user/login')
.POST<{username:string,password:string},{token:string}>()
//the develop tools will have type tips for request and response
login({username:'admin',password:'123'}).then(res=>{
localStorage.setItem('token', res.token);
})
English | 中文 | Installation
lither 是用 ts 对原生 fetch 的轻量封装
- 🌐 自动解析 rest Url 的参数
- ⭐ 快捷定义请求 api
- ⌛ 超时断开
- 🔤 自动处理 JSON
- 📏 不到 3K , zip 后会更小
- 💡 用 typescript 有智能类型提醒
示例
export const lither = createLither({
baseURL: baseURL,
timeout: 20 * 1000,
beforeRequest: (options) => {
const token = localStorage.getItem("token");
if (!token) return;
if (!options.headers) {
options.headers = new Headers();
}
options.headers.append("Authorization", token);
},
afterResponse: async (res, { resolve, reject }) => {
if (res.ok) {
if (res.responseHandler === "json") {
if (res.body.code === 0) {
resolve(res.body.data);
} else {
toast.error(res.body.err);
reject(res.body);
}
} else {
resolve(res.body ?? res);
}
} else if (res.status === 401) {
localStorage.removeItem("token");
location.href = "/login";
} else if (res.isTimeout) {
toast.error("timeout");
} else {
toast.error(res.error || res.statusText);
}
reject(res.error || res.body);
},
});
/** GET */
lither.get("/user?id=123").then((data) => console.log(data));
lither.get("/user", { query: { id: 123 } }).then((data) => console.log(data));
lither
.get("/user/:id", { params: { id: 123 } })
.then((data) => console.log(data));
/** POST */
lither
.post("/login", { body: { username: "admin", password: "123456" } })
.then((data) => console.log(data));
/**定义 API */
export const login = lither
.API("/user/login")
.POST<{ username: string; password: string }, { token: string }>();
login({ username: "admin", password: "123" }).then((res) => {
localStorage.setItem("token", res.token);
});
API 参考
请求
lither.request(url[,options])
请求数据可以选择 query
params
body
,易于传递。
type LitherOptions = {
/** url ?后的参数 `api/info?name=yes` 传递 {name:"yes"}*/
query?:
| Record<
string,
string | number | boolean | string[] | number[] | null | undefined
>
| URLSearchParams;
/** rest风格url的请求参数 `api/info/:id` 传递 {id:1}*/
params?: Record<string, string | number>;
/** 默认 'text',若响应 content-type 有 json,便用 json */
responseHandler?: "arrayBuffer" | "blob" | "formData" | "json" | "text";
/** unit 毫秒 */
timeout?: number;
/*** 原生fetch 参数*/
//可直接传递JSON而不必stringified
body?: any;
signal?: AbortSignal;
method?:
| "get"
| "GET"
| "delete"
| "DELETE"
| "head"
| "HEAD"
| "options"
| "OPTIONS"
| "post"
| "POST"
| "put"
| "PUT"
| "patch"
| "PATCH"
| "purge"
| "PURGE"
| "link"
| "LINK"
| "unlink"
| "UNLINK";
mode?: "cors" | "no-cors" | "same-origin";
cache?: "default" | "no-cache" | "reload" | "force-cache" | "only-if-cached";
credentials?: "include" | "same-origin" | "omit";
headers?: Headers;
redirect?: "manual" | "follow" | "error";
referrerPolicy?:
| "no-referrer"
| "no-referrer-when-downgrade"
| "origin"
| "origin-when-cross-origin"
| "same-origin"
| "strict-origin"
| "strict-origin-when-cross-origin"
| "unsafe-url";
integrity?: string;
};
响应
type litherResponse = {
isTimeout: boolean;
error?: any;
responseHandler?: "arrayBuffer" | "blob" | "formData" | "json" | "text";
method:
| "get"
| "GET"
| "delete"
| "DELETE"
| "head"
| "HEAD"
| "options"
| "OPTIONS"
| "post"
| "POST"
| "put"
| "PUT"
| "patch"
| "PATCH"
| "purge"
| "PURGE"
| "link"
| "LINK"
| "unlink"
| "UNLINK";
// *************原生 fetch 参数******************
/** body已根据 responseHandler选项处理过 */
body?: any;
url: string;
ok?: boolean;
headers?: Headers;
redirected?: boolean;
status?: number;
statusText?: string;
type?: string;
};
默认配置
import {createLither} from 'lither'
createLither(init: LitherInit): Lither
type LitherInit = {
//**url prefix */
baseURL?: string;
//**unit ms */
timeout?: number;
beforeRequest?: (options: LitherOptions) => void;
afterResponse?: (response: litherResponse, { resolve, reject, }: {
resolve: (value: any) => void;
reject: (reason?: any) => void;
}) => void;
};
特别功能
快捷方法
lither.get(url, options);
lither.post(url, options);
lither.put(url, options);
lither.patch(url, options);
lither.delete(url, options);
lither.head(url, options);
lither.options(url, options);
Restful Url 参数自动处理
url 包含 /:key 会解析匹配 key
lither.get("/api/user/:id", { params: { id: 1 } });
// api/user/1
lither.get("/api/:job/:year", { params: { job: "engineer", year: 5 } });
//api/engineer/5
超时
//** 请求级超时, 会覆盖实例级超时 */
lither.get(url, { timeout: 1000 * 20 });
快速定义 API
//可以是 GET POST PATCH PUT DELETE
//GET 请求数据传递至query,其他方法请求数据传递至body
lither.API(url:string).POST<RequestType,ResponseType>()
//定义一个api
export const getUserInfo=lither.API('/user/:id').GET()
//使用
getUserInfo({id:2})
.then(res=>console.log(res))
.catch(err=>console.log(err))
//用typescript,
export const login=lither.API('/user/login')
.POST<{username:string,password:string},{token:string}>()
//开发工具会有请求和响应的智能提醒
login({username:'admin',password:'123'}).then(res=>{
localStorage.setItem('token', res.token);
})
安装 Installation
npm install lither