Scenario-based patterns for @aurelia/fetch-client that solve common API challenges like auth, caching, and uploads.
Use these patterns when you know the experience you want - resilient API calls, cache-friendly dashboards, or abortable uploads - and need the exact configuration steps.
1. Token-aware API client with automatic retries
Goal: Add an Authorization header to every request, refresh expired tokens, and retry transient 5xx errors with exponential backoff.
Steps
Configure the shared IHttpClient once during app startup:
Use helper methods (http.get, http.post, etc.) everywhere else - each call now benefits from the shared interceptors and retry policy.
Checklist
Expired tokens trigger exactly one refresh and replay of the original request.
5xx responses retry with exponential delays, verified by watching network logs.
http.rejectErrorResponses() makes failed HTTP status codes reject Promises so callers can catch them.
2. Stale-while-revalidate dashboards
Goal: Cache GET responses for a few minutes, immediately serve stale data if needed, and refresh in the background so dashboards feel instant.
Steps
Instantiate the cache interceptor via DI (it needs access to ICacheService):
Register the interceptor when configuring the client:
Fetch dashboards via http.get('/dashboards/overview') - the interceptor handles cache reads or writes.
Checklist
First load hits the network; subsequent loads within cacheTime resolve instantly.
When the cache is stale, users see cached data immediately and fresh data appears shortly after (refresh interval logs confirm the background fetch).
Non-GET requests bypass the cache automatically.
3. Abortable uploads with progress feedback
Goal: Let users cancel long uploads and show progress using the same client instance.
Steps
Build a wrapper that creates an AbortController per upload:
Use the browser’s upload progress events (e.g., XHR or a custom uploader) if you need granular progress numbers; Fetch itself does not emit upload progress, but you can still expose a spinner tied to http.isRequesting or the activeRequestCount.
Checklist
Calling cancel() triggers AbortError, which you can catch to reset UI state.
http.isRequesting flips to true while uploads run, so global loading indicators stay accurate.
Multiple uploads in parallel each get their own controller, preventing accidental cross-cancellation.
4. Time-boxed requests with automatic timeout
Goal: Cancel any request that takes longer than a threshold (for example, 8 seconds) and show a friendly timeout message.
Steps
Wrap http.fetch so each call gets an AbortController plus a timeout:
Use it wherever you need snappy UX:
Checklist
Requests that exceed the timeout trigger AbortError and can be handled centrally.
Successful responses clear the timeout to avoid leaks.
Global loading indicators drop immediately after the abort because http.isRequesting returns to false.
5. Correlated requests with logging
Goal: Attach a unique correlation ID to every request for troubleshooting and log response times without sprinkling code across services.
Steps
Add an interceptor that stamps IDs and measures duration (store timings in a WeakMap so you can read them later):
If your server needs to read the correlation ID, emit the header from the request before forwarding it upstream.
Consume the logs in your monitoring system or browser console.
Checklist
Every network call carries an X-Request-Id header visible in browser dev tools.
Logs show the correlation ID, status, URL, and elapsed time.
The interceptor lives in one place, so adding fields (tenant, locale) is straightforward.