restigo v1.0.4
Restigo
Restigo is a promise based, HTTP REST Client built on top of axios
and cachios
packages suggesting easy to use and extensively customizable and configurable service with CRUD methods and type safe requests to API.
Installation
Using npm
npm install restigo
Using yarn
yarn add restigo
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
or cachios
Instances
โ๏ธ 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 - restigo has 100% test coverage
Usage / Examples
๐งฑ Basic
1) Create Instance
import restigo from "restigo";
const instance = restigo.create({ baseURL: "http://localhost:5000" });
2) Create Service
import { instance } from "./restigoInstance";
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 { RestigoService } from "restigo";
import { instance } from "./restigoInstance";
export class UserService extends RestigoService<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 RestigoService<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 restigoInstance
Example:
import { instance } from "./restigoInstance";
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
๐ Restigo Instance
Create Restigo Instance based axios
or cachios
Instance with restigo.create()
Function
import restigo from "restigo";
/* Customised Restigo Instance can be based on
AxiosInstance, AxiosRequestConfig or CachiosInstance */
const restigoInstance = restigo.create(/* Here goes instance or config*/);
Options to configure restigo.create()
type InstanceConfig = AxiosInstance | CachiosInstance | AxiosRequestConfig;
๐ Restigo 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 "./restigoInstance";
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 CachiosRequestConfig
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 "./restigoInstance";
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 "./restigoInstance";
const userService = instance.createService<UserWithId, User, number>("user", {
payloadKey: "update",
payloadKeyByMethod: { post: "data" },
});