4rest 中文文档教程
Description
4rest (Forest) 是一个基于承诺的 HTTP REST 客户端,构建于 之上axios
包建议使用 CRUD 方法和类型安全的 API 请求使用易于使用且可广泛定制和配置的服务。
Installation
使用 npm
npm install 4rest
使用 yarn
yarn add 4rest
Features
内置 CRUD 方法的服务:
- getAll
- getById
- deleteAll
- deleteById
- post
- patch
- put
自定义服务,可以选择添加额外的方法来扩展服务内置的 CRUD 方法
???? 服务构建完全可配置的 axios
实例
⚙️ 方便配置自定义路由、请求配置和有效负载数据(请求的主体属性)关键自定义定义
????️ Type Safe API 获取请求、有效负载和响应
? 测试证明 - 4rest 具有 100% 的测试覆盖率
Usage / Examples
Basic
1) Create Instance
import forest from "4rest";
const instance = forest.create({ baseURL: "http://localhost:5000" });
2) Create Service
import { instance } from "./forestInstance";
import { UserWithId, User } from "./types";
const userService = instance.createService<UserWithId, User>("user");
3) Use Service
- #### GET
// GET http://localhost:5000/user
async function getUsers() {
const users: User[] = await (await userService.getAll()).data;
}
// GET http://localhost:5000/user/:id
async function getUserById(id: string) {
const user: User = await (await userService.getById(id)).data;
}
- #### DELETE
// DELETE http://localhost:5000/user
async function deleteAllUsers() {
const usersDeleted: User[] = await (await userService.deleteAll()).data;
}
// DELETE http://localhost:5000/user/:id
async function deleteUserById(id: ObjectId) {
const userDeleted: User = await (await userService.deleteById(id)).data;
}
- #### POST
// POST http://localhost:5000/user
async function createUser(newUser: User) {
const userCreated: User = await (await userService.post(newUser)).data;
}
- #### PATCH
// PATCH http://localhost:5000/user
async function updateUser(partialUser: Partial<User>) {
const updatedUser: User = await (await userService.patch(partialUser)).data;
}
- #### PUT
// PUT http://localhost:5000/user
async function updateUser(partialUser: Partial<User>) {
const updatedUser: User = await (await userService.put(partialUser)).data;
}
Custom
1) Create Custom Service
import { ForestService } from "4rest";
import { instance } from "./forestInstance";
export class UserService extends ForestService<UserWithId, User> {
constructor(config?: ServiceConfig) {
super("user", instance, config);
/* prefix for request url is "user" */
}
public getByFullname = this.methods.getByParam<UserWithId, string>(
"fullName"
);
public isEmailTaken = this.methods.getByParam<boolean, string>([
"email",
"taken",
]);
}
2) Use Custom Service
const userService = new UserService();
async function getUserByFullname(fullname: string) {
const user: User = await (await userService.getByFullname(fullname)).data;
}
async function isEmailTaken(email: string) {
const isEmailTaken: boolean = await (
await userService.isEmailTaken(email)
).data;
}
Types
服务 具有通用类型来控制以下服务方法的类型
- Response Data
- Payload Data
- Id Type
class ForestService<ResponseData = any, PayloadData = Response, IdType = string>
这样,Typescript 将强制您在调用服务方法时为其提供具有匹配类型的参数,或者将单独识别响应数据类型以便将来更舒适地自动完成。
在使用 forestInstance
的 createService()
函数创建新服务时传递此通用类型
示例:
import { instance } from "./forestInstance";
import { UserWithId, User } from "./types";
const userService = instance.createService<UserWithId, User, string>("user");
// ResponseData - UserWithId
// PayloadData - User
// IdType - string
默认情况下服务采用您传递给它的类型,并按以下方式将它们转换为每个服务方法:
getAll
- Response Data Type:
ResponseData[]
getById
- Response Data Type:
ResponseData
- Id Type:
IdType
DeleteAll
- Response Data Type:
ResponseData[]
deleteById
- Response Data Type:
ResponseData
- Id Type:
IdType
post
- Response Data Type:
ResponseData
- Payload Data Type:
PayloadData
patch
- Response Data Type:
ResponseData
- Payload Data Type:
Partial<PayloadData>
put
- Response Data Type:
ResponseData
- Payload Data Type:
Partial<PayloadData>
如果您想更改一种或多种此方法类型,您可以在调用该方法时通过传递给它的泛型类型来实现仅与此方法相关,在您调用它的地方。
示例:
假设您想将调用 post 方法返回的响应数据类型从 ResponseData
更改为 boolean,因为您使用的 API 仅返回指示 User 是否已成功创建的数据
。您可以通过以下方式执行此操作:
const data: boolean = await(
await userService.post<boolean>(/* newUserData */)
).data;
Configuration
Forest Instance
Create Forest Instance based axios
具有forest.create()
功能的实例
import forest from "4rest";
/* Customised Forest Instance can be based on
AxiosInstance, AxiosRequestConfig */
const forestInstance = forest.create(/* Here goes instance or config*/);
要配置的选项 forest.create()
type InstanceConfig = AxiosInstance | AxiosRequestConfig;
< br>
Forest Service
Configure Service with createService()
Method:
1) Methods REST Routes
您可能希望更改一些内置服务方法路由,以根据您正在使用的 API 扩展前缀。
通过为您想要的每种方法配置扩展路由,可以轻松做到这一点。
注意:没有配置扩展路由的方法会将请求发送到基本路由:baseUrl/prefix
或 baseUrl/prefix/param
示例:
import { instance } from "./forestInstance";
const userService = instance.createService<User>("user", {
/* All Service built in CRUD methods route control ( string | string[] ) */
routes: {
getAll: ["get", "all"], // GET http://localhost:5000/user/get/all
deleteAll: "all", // DELETE http://localhost:5000/user/all
deleteById: "id", // DELETE http://localhost:5000/user/id/:id
...,
post: "create", // POST http://localhost:5000/user/create
patch: "update" // POST http://localhost:5000/user/update
}
});
2) Request Config
您可以设置 AxiosRequestConfig
类型的 requestConfig
以将元数据附加到请求(如标头、参数等)
requestConfig
可以为每个方法单独设置,也可以为所有方法做一个通用配置
注意:如果一个方法有自己特定的requestConfig
,它将在一般方法上使用
示例:
import { instance } from "./forestInstance";
const userService = instance.createService<UserWithId, User, number>("user", {
requestConfigByMethod: {
/* Request Config Per Method */ getAll: { params: { page: 1, size: 10 } },
getById: { maxRedirects: 3 },
},
requestConfig: {
/* Request Config For All Methods */ headers: {
Authentication: "Bearer Header",
},
},
});
3) Payload Data Key
对于具有有效负载(Post、Patch、Put)的 HTTP 方法,您可以设置一个 payloadKey
来设置有效负载数据您想要在请求主体内的密钥
// By Default
request: {
body: data,
...
}
// After Setting payloadKey
request: {
body: {
[payloadKey]: data
},
...
}
payloadKey
可以为每个 HTTP 有效负载方法单独设置,或者为所有方法进行一个通用配置
注意:如果一个方法有自己特定的payloadKey
,它将在 一般的
示例:
import { instance } from "./forestInstance";
const userService = instance.createService<UserWithId, User, number>("user", {
payloadKey: "update",
payloadKeyByMethod: { post: "data" },
});
License
Description
4rest (Forest) is a promise based, HTTP REST Client built on top of axios
package suggesting easy to use and extensively customizable and configurable service with CRUD methods and type safe requests to API.
Installation
Using npm
npm install 4rest
Using yarn
yarn add 4rest
Features
???? Service with built in CRUD Methods:
- getAll
- getById
- deleteAll
- deleteById
- post
- patch
- put
???? Custom Services with option to add additional methods extending out CRUD methods that comes built in with the service
???? Services Built on fully configurable axios
Instance
⚙️ Convenient Configuration with custom routes, request configuration, and payload data (body property of request) key custom define
????️ Type Safe API fetching requests, payloads, and responses
???? Test Proof - 4rest has 100% test coverage
Usage / Examples
???? Basic
1) Create Instance
import forest from "4rest";
const instance = forest.create({ baseURL: "http://localhost:5000" });
2) Create Service
import { instance } from "./forestInstance";
import { UserWithId, User } from "./types";
const userService = instance.createService<UserWithId, User>("user");
3) Use Service
- #### GET
// GET http://localhost:5000/user
async function getUsers() {
const users: User[] = await (await userService.getAll()).data;
}
// GET http://localhost:5000/user/:id
async function getUserById(id: string) {
const user: User = await (await userService.getById(id)).data;
}
- #### DELETE
// DELETE http://localhost:5000/user
async function deleteAllUsers() {
const usersDeleted: User[] = await (await userService.deleteAll()).data;
}
// DELETE http://localhost:5000/user/:id
async function deleteUserById(id: ObjectId) {
const userDeleted: User = await (await userService.deleteById(id)).data;
}
- #### POST
// POST http://localhost:5000/user
async function createUser(newUser: User) {
const userCreated: User = await (await userService.post(newUser)).data;
}
- #### PATCH
// PATCH http://localhost:5000/user
async function updateUser(partialUser: Partial<User>) {
const updatedUser: User = await (await userService.patch(partialUser)).data;
}
- #### PUT
// PUT http://localhost:5000/user
async function updateUser(partialUser: Partial<User>) {
const updatedUser: User = await (await userService.put(partialUser)).data;
}
???? Custom
1) Create Custom Service
import { ForestService } from "4rest";
import { instance } from "./forestInstance";
export class UserService extends ForestService<UserWithId, User> {
constructor(config?: ServiceConfig) {
super("user", instance, config);
/* prefix for request url is "user" */
}
public getByFullname = this.methods.getByParam<UserWithId, string>(
"fullName"
);
public isEmailTaken = this.methods.getByParam<boolean, string>([
"email",
"taken",
]);
}
2) Use Custom Service
const userService = new UserService();
async function getUserByFullname(fullname: string) {
const user: User = await (await userService.getByFullname(fullname)).data;
}
async function isEmailTaken(email: string) {
const isEmailTaken: boolean = await (
await userService.isEmailTaken(email)
).data;
}
Types
Service has generic types to control the following types of the service methods
- Response Data
- Payload Data
- Id Type
class ForestService<ResponseData = any, PayloadData = Response, IdType = string>
By doing so, Typescript will force you to give it the parameters with matching types when calling the service methods or will recognize alone the response data type for more comfortable auto-completion in the future.
You pass this generic types when creating new service with createService()
function of a forestInstance
Example:
import { instance } from "./forestInstance";
import { UserWithId, User } from "./types";
const userService = instance.createService<UserWithId, User, string>("user");
// ResponseData - UserWithId
// PayloadData - User
// IdType - string
By default the service takes the types you passed to it and transform them to each service method in the following way:
getAll
- Response Data Type:
ResponseData[]
getById
- Response Data Type:
ResponseData
- Id Type:
IdType
DeleteAll
- Response Data Type:
ResponseData[]
deleteById
- Response Data Type:
ResponseData
- Id Type:
IdType
post
- Response Data Type:
ResponseData
- Payload Data Type:
PayloadData
patch
- Response Data Type:
ResponseData
- Payload Data Type:
Partial<PayloadData>
put
- Response Data Type:
ResponseData
- Payload Data Type:
Partial<PayloadData>
if you would like to change one or more of this method types, you can do it when calling the method by passing to it generic types that will be relevant to the this method only, at the place you are calling it.
Example:
Lets say you would like to change the type of the response data that comes back from calling to the post method from ResponseData
to boolean
because the API you working with is returns only with data that indicates whether or not an User has been created successfully
You can do that in the following way:
const data: boolean = await(
await userService.post<boolean>(/* newUserData */)
).data;
Configuration
???? Forest Instance
Create Forest Instance based axios
Instance with forest.create()
Function
import forest from "4rest";
/* Customised Forest Instance can be based on
AxiosInstance, AxiosRequestConfig */
const forestInstance = forest.create(/* Here goes instance or config*/);
Options to configure forest.create()
type InstanceConfig = AxiosInstance | AxiosRequestConfig;
???? Forest Service
Configure Service with createService()
Method:
1) Methods REST Routes
You may want to change few of the built in service method route to extend the prefix based on the API you are working with.
Do it easily by configuring an extended route for each method you want.
Note: method with no configured extended route will send request to basic route: baseUrl/prefix
or baseUrl/prefix/param
Example:
import { instance } from "./forestInstance";
const userService = instance.createService<User>("user", {
/* All Service built in CRUD methods route control ( string | string[] ) */
routes: {
getAll: ["get", "all"], // GET http://localhost:5000/user/get/all
deleteAll: "all", // DELETE http://localhost:5000/user/all
deleteById: "id", // DELETE http://localhost:5000/user/id/:id
...,
post: "create", // POST http://localhost:5000/user/create
patch: "update" // POST http://localhost:5000/user/update
}
});
2) Request Config
You can set a requestConfig
of type AxiosRequestConfig
for attaching metadata to a request (like headers, params, etc.)
requestConfig
can be set for each method seperatly or make one general config for all methods
Note: if a method has its own specific requestConfig
, it will be used over the general one
Example:
import { instance } from "./forestInstance";
const userService = instance.createService<UserWithId, User, number>("user", {
requestConfigByMethod: {
/* Request Config Per Method */ getAll: { params: { page: 1, size: 10 } },
getById: { maxRedirects: 3 },
},
requestConfig: {
/* Request Config For All Methods */ headers: {
Authentication: "Bearer Header",
},
},
});
3) Payload Data Key
For HTTP methods with payload (Post, Patch, Put) you can set a payloadKey
for setting the payload data on the key you want inside the body of the request
// By Default
request: {
body: data,
...
}
// After Setting payloadKey
request: {
body: {
[payloadKey]: data
},
...
}
payloadKey
can be set for each HTTP payload method seperatly or make one general config for all methods
Note: if a method has its own specific payloadKey
, it will be used over the general one
Example:
import { instance } from "./forestInstance";
const userService = instance.createService<UserWithId, User, number>("user", {
payloadKey: "update",
payloadKeyByMethod: { post: "data" },
});