@@ -3,7 +3,7 @@ layout: home
33hero :
44 name : Foundatio FetchClient
55 text : Typed, ergonomic fetch for JS/TS
6- tagline : JSON helpers, caching, middleware, rate limiting, and great DX
6+ tagline : JSON helpers, caching, middleware, rate limiting, circuit breaker, and great DX
77 image :
88 src : https://raw.githubusercontent.com/FoundatioFx/Foundatio/main/media/foundatio-icon.png
99 alt : Foundatio
@@ -15,28 +15,114 @@ hero:
1515 text : View on GitHub
1616 link : https://github.com/FoundatioFx/FetchClient
1717features :
18- - icon : ⚡
19- title : Typed Responses
20- details : Full TypeScript support for strongly-typed JSON results.
21- - icon : 🧩
22- title : Middleware & Caching
23- details : Compose middleware and cache responses with TTL.
24- - icon : 🎯
25- title : Rate Limits & Timeouts
26- details : Built-in rate limiting, timeouts, and robust error handling.
18+ - icon : " \u26A1 "
19+ title : Typed JSON Helpers
20+ details : getJSON, postJSON, putJSON, patchJSON, deleteJSON with full TypeScript support.
21+ - icon : " \uD83C\uDFAF "
22+ title : Two API Styles
23+ details : Use simple functions or classes - your choice. Both have full access to all features.
24+ - icon : " \uD83D\uDCBE "
25+ title : Response Caching
26+ details : TTL-based caching with cache keys and tags for grouped invalidation.
27+ - icon : " \uD83E\uDDE9 "
28+ title : Middleware
29+ details : Intercept requests and responses for logging, auth, transforms, and more.
30+ - icon : " \uD83D\uDEA6 "
31+ title : Rate Limiting
32+ details : Per-domain rate limits with automatic API header detection.
33+ - icon : " \uD83D\uDEE1\uFE0F "
34+ title : Circuit Breaker
35+ details : Prevent cascading failures when services go down.
36+ - icon : " \u23F1\uFE0F "
37+ title : Timeouts & Cancellation
38+ details : Request timeouts with native AbortSignal support.
39+ - icon : " \uD83E\uDDEA "
40+ title : Testing Built-in
41+ details : MockRegistry for mocking HTTP requests without network calls.
2742---
2843
2944## Quick Example
3045
46+ FetchClient works two ways - pick whichever style you prefer:
47+
48+ ### Functional API
49+
50+ ``` ts
51+ import { getJSON , postJSON , setBaseUrl } from " @foundatiofx/fetchclient" ;
52+
53+ setBaseUrl (" https://api.example.com" );
54+
55+ const { data : users } = await getJSON <User []>(" /users" );
56+ const { data : created } = await postJSON <User >(" /users" , { name: " Alice" });
57+ ```
58+
59+ Or use ` getFetchClient() ` for fewer imports:
60+
61+ ``` ts
62+ import { getFetchClient , setBaseUrl } from " @foundatiofx/fetchclient" ;
63+
64+ setBaseUrl (" https://api.example.com" );
65+
66+ const client = getFetchClient ();
67+ const { data : users } = await client .getJSON <User []>(" /users" );
68+ const { data : created } = await client .postJSON <User >(" /users" , { name: " Alice" });
69+ ```
70+
71+ ### Class-Based API
72+
3173``` ts
3274import { FetchClient } from " @foundatiofx/fetchclient" ;
3375
34- type Products = { products: Array <{ id: number ; name: string }> };
76+ const client = new FetchClient ({ baseUrl: " https://api.example.com" });
77+ const { data } = await client .getJSON <User []>(" /users" );
78+ ```
79+
80+ ## Caching
81+
82+ ``` ts
83+ const { data } = await getJSON <User >(" /api/users/1" , {
84+ cacheKey: [" users" , " 1" ],
85+ cacheDuration: 60000 ,
86+ cacheTags: [" users" ],
87+ });
88+
89+ // Invalidate all user cache entries
90+ getCurrentProvider ().cache .deleteByTag (" users" );
91+ ```
92+
93+ ## Middleware
94+
95+ ``` ts
96+ import { useMiddleware } from " @foundatiofx/fetchclient" ;
97+
98+ useMiddleware (async (ctx , next ) => {
99+ console .log (" Request:" , ctx .request .url );
100+ await next ();
101+ console .log (" Response:" , ctx .response ?.status );
102+ });
103+ ```
104+
105+ ## Rate Limiting & Circuit Breaker
106+
107+ ``` ts
108+ import { usePerDomainRateLimit , useCircuitBreaker } from " @foundatiofx/fetchclient" ;
109+
110+ // Prevent overwhelming APIs
111+ usePerDomainRateLimit ({ maxRequests: 100 , windowSeconds: 60 });
112+
113+ // Stop requests when services fail
114+ useCircuitBreaker ({ failureThreshold: 5 , openDurationMs: 30000 });
115+ ```
116+
117+ ## Testing
118+
119+ ``` ts
120+ import { MockRegistry } from " @foundatiofx/fetchclient/mocks" ;
35121
36- const client = new FetchClient ();
37- const res = await client .getJSON <Products >(
38- ` https://dummyjson.com/products/search?q=iphone&limit=10 ` ,
39- );
122+ const mocks = new MockRegistry ();
123+ mocks .onGet (" /api/users" ).reply (200 , [{ id: 1 , name: " Alice" }]);
124+ mocks .install (provider );
40125
41- console .log (res .data ?.products .length );
126+ // Requests are mocked - no network calls
127+ const { data } = await getJSON (" /api/users" );
42128```
0 commit comments