Fetchfully wraps the JavaScript Fetch API with additional functionalities for simplicity and efficiency. It's the Javascript Fetch API with Power Pack ⚡️
- Object-first data fetching: Supply all init config as object, improving code clarity.
- In-built request Logic: Automatically handles responses based on content type.
- Parses JSON payload: Parses mutation request payload as JSON.
- Simple path and query parameters: Work better with URL parameters. Pass path and query parameter as object value. Tweak query parameters delimiter in config.
- Global config and instances: Create different instances that use a global config or override it with instance-specific config.
- Consumable request method: Use consumable methods for ergonomic common HTTP requests.
- Request status: Monitor request status for loading, failed and successful network request states.
- Refetch request: Easily make refetch without reconstructing request config.
- Fully Type: Use Typescript and exports all necessary types for easy configuration
Install the package using npm or yarn:
npm install fetchfullyNOTE: The API endpoints below are for demonstration purposes only. Test on live endpoints for expected result.
import fetcher from "fetchfully";
await fetcher({ url: "https://api.example.com/posts" });await fetcher({
url: "https://api.example.com",
path: "posts1/comments",
});
// URL results in: https://api.example.com/posts/1/commmentsawait fetcher({
url: "https://api.example.com",
path: ["posts", "1", "comments"],
});
// URL results in: https://api.example.com/posts/1/commmentsconst query = {
page: 1,
limit: 10,
colors: ["red", "blue"],
size: "large",
};
await fetcher({
url: "https://api.example.com",
query,
queryArrayFormat = "comma",
});
// URL results in: https://api.example.com/comments?page=1&limit=10&colors=red,blue&size=largeawait fetcher({
url: "https://api.example.com/post",
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: {
title: "foo",
body: "bar",
userId: 1,
},
});await fetcher({
url: "https://api.example.com/post",
method: "PUT",
headers: {
Authorization: "Bearer token",
"Content-Type": "application/json",
},
body: {
id: 1,
title: "foo",
body: "bar",
userId: 1,
},
});await fetcher({
url: "https://api.example.com/post/1",
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: { title: "bar" },
});await fetcher({ url: "https://api.example.com/post/1", method: "DELETE" });When initializing Fetchfully, you can pass the following options:
| Option | Type | Description |
|---|---|---|
baseUrl |
String |
Base URL for all requests. |
path |
string | string[] | undefined |
URL path segments. |
query |
string | string[] | undefined |
URL query parameters. |
method |
string |
Request action method. |
body |
string | undefined |
Request payload. |
credentials |
"same-origin" | "omit" | "include" |
Request credentials. |
keepalive |
boolean |
Persist requests request connection. |
mode |
"same-origin" | "cors" | "no-cors" |
Request CORS mode. |
timeout |
number |
Time as milliseconds before terminating request. |
queryArrayFormat |
"brackets" | "comma" | "repeat" | "none" |
Indicates how parameter array should be formatted. |
Create new instance of Fetchfully with independent custom configurations with the fetcher.create() factory method.
import fetcher from "fetchfully";
// api/auth
const authAPI = fetchfully.create({
baseUrl: "https://api.example.com/auth",
timeout: 5000,
});
// api/users
const userAPI = fetcher.create({
baseURL: "https://api.example.com/user",
headers: {
"Cache-Control": "no-cache",
},
});
// api/analytics
const analyticsAPI = fetcher.create({
baseURL: "https://api.example.com/analytics",
timeout: 5000,
});Create a global config that will persist across all requests
import fetcher from "fetchfully";
fetcher.defaults.baseUrl = "https://api.example.com";
fetcher.defaults.timeout = 5000;const customAPI = fetcher.create({
headers: {
Authorization: "Bearer token", // Instance specific authorization header
},
timeout: 2500, // Instance specific timeout.
});
// Use custom instance
await customAPI({
path: "users",
query: { active: true }, // 'https://api.example.com/users?active=true
});Instance specific configs take precedence over those in global default config. For instance, the 2500 (2.5 seconds) set above is specific to that instance alone.
Use these ergonomic methods for common HTTP request.
import fetcher from "fetchfully";
fetcher.defaults.baseUrl = "https://api.example.com";// Using convenience methods
await fetcher.get("users");
await fetcher.get("users", { active: true }); // https://api.example.com/users?active=trueawait fetcher.post("users", {
name: "John",
email: "[email protected]",
});await fetcher.put("users/123", {
name: "John Doe",
});await fetcher.patch("users/123", {
status: "active",
});await fetcher.delete("users/123");The refetch method lets you re-run the exact same request with the same configuration to get fresh data without reconstructing entire request.
// Example 1: Basic refetch
const response = await fetchfully.get("/api/users");
if (response.isSuccess) {
console.log("Users:", response.data);
const freshResponse = await response.refetch?.();
console.log("Updated users:", freshResponse.data);
}
// Example 2: Refetch on user action
const userResponse = await fetchfully.get("/api/user/123");
const handleRefresh = async () => {
if (userResponse.refetch) {
const refreshed = await userResponse.refetch();
if (refreshed.isSuccess) {
setUser(refreshed.data); // Update UI with fresh data
}
}
};This project is licensed under the MIT.