Skip to content

Commit 5cb99d8

Browse files
authored
Merge pull request #71 from MattCCC/fetchf-custom-fetcher
Add custom fetcher to fetchf()
2 parents 0d58aa3 + 96168b3 commit 5cb99d8

8 files changed

+245
-186
lines changed

.npmignore

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ node_modules
77
package
88
docs
99

10-
CODE_OF_CONDUCT.md
1110
SECURITY.md
1211

1312
*.tgz

FUNDING.md

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Funding for fetchff
2+
3+
fetchff is an open-source project aimed at simplifying and enhancing HTTP requests in JavaScript applications. As an open-source project, it thrives on community support and contributions. Your support helps ensure that fetchff remains sustainable and continues to grow. If you find fetchff useful and would like to support its ongoing development, here are a few ways you can help:
4+
5+
## Ways to Support
6+
7+
### 1. **GitHub Sponsorship**
8+
9+
You can sponsor the fetchff project directly on GitHub. Your contributions help cover development costs and allow us to invest more time into improving the library.
10+
11+
<i>[This option is currently unavailable]</i>
12+
13+
<!-- [Become a Sponsor on GitHub](https://github.com/sponsors) -->
14+
15+
### 2. **Patreon**
16+
17+
Consider supporting fetchff through Patreon. Your monthly contributions will provide us with the resources needed to maintain and enhance the project.
18+
19+
[Support Us on Patreon](https://www.patreon.com/mattccc)
20+
21+
### 3. **Contributions**
22+
23+
If financial support isn't feasible for you at the moment, there are other ways to contribute:
24+
25+
- **Report Issues**: Help us identify bugs or areas for improvement by reporting issues on GitHub.
26+
- **Feature Requests**: Share your ideas for new features or enhancements.
27+
- **Documentation**: Contribute to our documentation to help others understand and use fetchff more effectively.
28+
- **Spread the Word**: Share fetchff with your colleagues and on social media. The more users we have, the more vibrant our community becomes!
29+
30+
## Thank You!
31+
32+
Your support, whether financial or in the form of contributions, helps ensure the longevity and success of fetchff. Together, we can make this project sustainable and even better!
33+
34+
---
35+
36+
For more information on how to contribute to fetchff, please refer to our [CONTRIBUTING.md](./CONTRIBUTING.md) file.

README.md

+30-31
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,11 @@ const { data, error } = await api.getUser({
175175
<summary><span style="cursor:pointer">Click to expand</span></summary>
176176
<br>
177177

178-
All the Request Settings can be used directly in the function or in the `endpoints` property (on per-endpoint basis). There are also two extra global settings for `createApiFetcher()`:
178+
All the Request Settings can be directly used in the function as global settings for all endpoints. They can be also used within the `endpoints` property (on per-endpoint basis). The exposed `endpoints` property is as follows:
179179

180-
| Name | Type | Default | Description |
181-
| --------- | ----------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
182-
| endpoints | `object` | | List of your endpoints. Each endpoint accepts all the settings below. They can be set globally, per-endpoint or per-request. |
183-
| fetcher | `FetcherInstance` | | A custom adapter (an instance / object) that exposes `create()` function so to create instance of API Fetcher. The `create()` should return `request()` function that would be used when making the requests. The native `fetch()` is used if the fetcher is not provided. |
180+
- **`endpoints`**:
181+
Type: `EndpointsConfig<EndpointsMethods>`
182+
List of your endpoints. Each endpoint is an object that accepts all the Request Settings (see the Basic Settings below). The endpoints are required to be specified.
184183

185184
#### How It Works
186185

@@ -206,7 +205,7 @@ import { createApiFetcher } from 'fetchff';
206205
const api = createApiFetcher({
207206
apiUrl: 'https://example.com/api',
208207
endpoints: {
209-
updateUserData: {
208+
updateUser: {
210209
url: '/update-user/:id',
211210
method: 'POST',
212211
},
@@ -215,7 +214,7 @@ const api = createApiFetcher({
215214
});
216215

217216
// Using api.request to make a POST request
218-
const { data, error } = await api.request('updateUserData', {
217+
const { data, error } = await api.request('updateUser', {
219218
body: {
220219
name: 'John Doe', // Data Payload
221220
},
@@ -279,7 +278,8 @@ You can also use all native `fetch()` settings.
279278
| withCredentials | `boolean` | `false` | Indicates whether credentials (such as cookies) should be included with the request. |
280279
| timeout | `number` | `30000` | You can set a request timeout for all requests or particular in milliseconds. |
281280
| dedupeTime | `number` | `1000` | Time window, in milliseconds, during which identical requests are deduplicated (treated as single request). |
282-
| logger | `object` | `null` | You can additionally specify logger object with your custom logger to automatically log the errors to the console. It should contain at least `error` and `warn` functions. |
281+
| logger | `Logger` | `null` | You can additionally specify logger object with your custom logger to automatically log the errors to the console. It should contain at least `error` and `warn` functions. |
282+
| fetcher | `FetcherInstance` | | A custom adapter (an instance / object) that exposes `create()` function so to create instance of API Fetcher. The `create()` should return `request()` function that would be used when making the requests. The native `fetch()` is used if the fetcher is not provided. |
283283

284284
## 🏷️ Headers
285285

@@ -291,25 +291,6 @@ You can also use all native `fetch()` settings.
291291

292292
**Note:** Header keys are case-sensitive when specified in request objects. Ensure that the keys are provided in the correct case to avoid issues with header handling.
293293

294-
### How to Set Per-Request Headers
295-
296-
To set headers for a specific request, include the `headers` option in the request configuration. This option accepts an `object` where the keys are the header names and the values are the corresponding header values.
297-
298-
### Default Headers
299-
300-
The `fetchff` plugin automatically injects a set of default headers into every request. These default headers help ensure that requests are consistent and include necessary information for the server to process them correctly.
301-
302-
#### Default Headers Injected
303-
304-
- **`Content-Type`**: `application/json;charset=utf-8`
305-
Specifies that the request body contains JSON data and sets the character encoding to UTF-8.
306-
307-
- **`Accept`**: `application/json, text/plain, */*`
308-
Indicates the media types that the client is willing to receive from the server. This includes JSON, plain text, and any other types.
309-
310-
- **`Accept-Encoding`**: `gzip, deflate, br`
311-
Specifies the content encoding that the client can understand, including gzip, deflate, and Brotli compression.
312-
313294
### Setting Headers Globally
314295

315296
You can set default headers that will be included in all requests made with a specific `createApiFetcher` instance. This is useful for setting common headers like authentication tokens or content types.
@@ -347,6 +328,19 @@ const { data } = await fetchf('https://api.example.com/endpoint', {
347328
});
348329
```
349330

331+
### Default Headers
332+
333+
The `fetchff` plugin automatically injects a set of default headers into every request. These default headers help ensure that requests are consistent and include necessary information for the server to process them correctly.
334+
335+
- **`Content-Type`**: `application/json;charset=utf-8`
336+
Specifies that the request body contains JSON data and sets the character encoding to UTF-8.
337+
338+
- **`Accept`**: `application/json, text/plain, */*`
339+
Indicates the media types that the client is willing to receive from the server. This includes JSON, plain text, and any other types.
340+
341+
- **`Accept-Encoding`**: `gzip, deflate, br`
342+
Specifies the content encoding that the client can understand, including gzip, deflate, and Brotli compression.
343+
350344
</details>
351345

352346
## 🌀 Interceptors
@@ -852,6 +846,7 @@ For a complete list of types and their definitions, refer to the [request-handle
852846
| **Unified API Client** | ✅ | -- | -- | -- | -- |
853847
| **Smart Request Cache** | ✅ | -- | -- | -- | -- |
854848
| **Automatic Request Deduplication** | ✅ | -- | -- | -- | -- |
849+
| **Custom Fetching Adapter** | ✅ | -- | -- | -- | -- |
855850
| **Built-in Error Handling** | ✅ | -- | ✅ | -- | -- |
856851
| **Customizable Error Handling** | ✅ | -- | ✅ | ✅ | -- |
857852
| **Retries with exponential backoff** | ✅ | -- | -- | -- | -- |
@@ -911,6 +906,10 @@ const api = createApiFetcher({
911906
method: 'get', // Default request method.
912907
params: {}, // Default params added to all requests.
913908
data: {}, // Alias for 'body'. Default data passed to POST, PUT, DELETE and PATCH requests.
909+
cacheTime: 300, // Cache is valid for 5 minutes
910+
cacheKey: (config) => `${config.url}-${config.method}`, // Custom cache key based on URL and method
911+
cacheBuster: (config) => config.method === 'POST', // Bust cache for POST requests
912+
skipCache: (response, config) => response.status !== 200, // Skip caching on non-200 responses
914913
onError(error) {
915914
// Interceptor on error
916915
console.error('Request failed', error);
@@ -1449,7 +1448,7 @@ fetchUserAndCreatePost(1, { title: 'New Post', content: 'This is a new post.' })
14491448
<details>
14501449
<summary><span style="cursor:pointer">Click to expand</span></summary>
14511450
<br>
1452-
You can implement a `useApi()` hook to handle the data fetching. Since this package has everything included, you don't really need anything more than a simple hook to utilize.<br><br>
1451+
You can implement a `useFetcher()` hook to handle the data fetching. Since this package has everything included, you don't really need anything more than a simple hook to utilize.<br><br>
14531452
14541453
Create `api.ts` file:
14551454
@@ -1467,10 +1466,10 @@ export const api = createApiFetcher({
14671466
});
14681467
```
14691468
1470-
Create `useApi.ts` file:
1469+
Create `useFetcher.ts` file:
14711470
14721471
```tsx
1473-
export const useApi = (apiFunction) => {
1472+
export const useFetcher = (apiFunction) => {
14741473
const [data, setData] = useState(null);
14751474
const [error] = useState(null);
14761475
const [isLoading, setLoading] = useState(true);
@@ -1505,7 +1504,7 @@ export const ProfileComponent = ({ id }) => {
15051504
data: profile,
15061505
error,
15071506
isLoading,
1508-
} = useApi(() => api.getProfile({ urlPathParams: { id } }));
1507+
} = useFetcher(() => api.getProfile({ urlPathParams: { id } }));
15091508
15101509
if (isLoading) return <div>Loading...</div>;
15111510
if (error) return <div>Error: {error.message}</div>;

src/.npmignore

-18
This file was deleted.

0 commit comments

Comments
 (0)