Utilities and Lifecycle

This guide covers advanced utilities, lifecycle methods, error handling, and cache implementation details for the Aurelia Fetch Client.

Advanced HttpClient Methods

buildRequest()

The buildRequest() method allows you to construct a Request object using the HttpClient's configuration without actually sending the request. This is useful for request inspection, manual request manipulation, or integration with other libraries.

Method Signature

buildRequest(input: string | Request, init?: RequestInit): Request

How It Works

The buildRequest() method:

  1. Applies the client's baseUrl to relative URLs

  2. Merges the client's default RequestInit settings with provided options

  3. Applies default headers

  4. Auto-detects JSON content and sets appropriate Content-Type header

  5. Returns a fully-configured Request object

Basic Usage

import { IHttpClient } from '@aurelia/fetch-client';
import { resolve } from '@aurelia/kernel';

export class RequestBuilderService {
  private http = resolve(IHttpClient);

  constructor() {
    this.http.configure(config => config
      .withBaseUrl('https://api.example.com')
      .withDefaults({
        headers: {
          'Authorization': 'Bearer token123',
          'Accept': 'application/json'
        }
      })
    );
  }

  buildExampleRequest() {
    // Build a request without sending it
    const request = this.http.buildRequest('/users/123');

    console.log(request.url);        // 'https://api.example.com/users/123'
    console.log(request.method);     // 'GET'
    console.log(request.headers.get('Authorization')); // 'Bearer token123'
    console.log(request.headers.get('Accept'));        // 'application/json'

    return request;
  }
}

Advanced Request Building

Practical Use Cases

1. Request Inspection and Debugging

2. Manual Request Queue Management

3. Integration with Third-Party Libraries

4. Conditional Request Execution

Important Notes

  1. BaseURL Resolution: Relative URLs are resolved against the configured baseUrl

  2. Header Merging: Default headers are merged with request-specific headers (request headers take precedence)

  3. Content-Type Detection: JSON bodies automatically get Content-Type: application/json

  4. Request Reusability: Built Request objects can be reused with fetch() but remember that request bodies can only be read once

dispose()

The dispose() method performs cleanup of the HttpClient instance, releasing resources and cleaning up interceptors.

Method Signature

What It Does

When dispose() is called:

  1. Calls dispose() on all registered interceptors (if they implement it)

  2. Clears the interceptor array

  3. Removes the event dispatcher reference

Basic Usage

Interceptor Cleanup

Interceptors can implement a dispose() method for cleanup:

Component Lifecycle Integration

Integrate with Aurelia component lifecycle:

Complete Cleanup Example

Best Practices

  1. Always implement cleanup: If your interceptor allocates resources, implement dispose()

  2. Component integration: Call http.dispose() in component dispose() methods

  3. Singleton clients: For application-scoped clients, dispose on application shutdown

  4. Testing: Always dispose clients in test cleanup to prevent memory leaks

Utility Functions

json()

A utility function for serializing objects to JSON strings, primarily for creating request bodies.

Function Signature

Basic Usage

With Request Body

Custom Replacer Function

The replacer parameter allows you to customize serialization:

Handling Edge Cases

Practical Examples

API Request Builder

Data Sanitization

Comparison with JSON.stringify()

Error Handling

The Fetch Client includes a comprehensive error code system for debugging and error handling.

Error Code System

All errors from the Fetch Client use the AUR50XX code range and include helpful error messages in development mode.

Error Codes Reference

AUR5000: Fetch Function Not Found

Error Message: "Could not resolve fetch function. Please provide a fetch function implementation or a polyfill for the global fetch function."

Cause: The global fetch function is not available.

Solution: Provide a fetch polyfill or implementation:

AUR5001: Invalid Configuration Return

Error Message: "The config callback did not return a valid HttpClientConfiguration like instance. Received {type}"

Cause: Configuration callback returned an invalid value.

Solution: Ensure your configuration callback returns a valid configuration:

AUR5002: Invalid Configuration Type

Error Message: "invalid config, expecting a function or an object, received {type}"

Cause: Called configure() with an invalid argument type.

Solution: Pass either a function or RequestInit object:

AUR5003: Invalid Default Headers

Error Message: "Default headers must be a plain object."

Cause: Provided a Headers instance instead of a plain object for default headers.

Solution: Use plain objects for default headers:

AUR5004: Multiple Retry Interceptors

Error Message: "Only one RetryInterceptor is allowed."

Cause: Attempted to register more than one RetryInterceptor.

Solution: Use only one retry interceptor:

AUR5005: Retry Interceptor Not Last

Error Message: "The retry interceptor must be the last interceptor defined."

Cause: The retry interceptor was not registered as the final interceptor.

Solution: Always register retry interceptor last:

AUR5006: Invalid Interceptor Result

Error Message: "An invalid result was returned by the interceptor chain. Expected a Request or Response instance, but got [{value}]"

Cause: An interceptor returned an invalid value (not a Request or Response).

Solution: Ensure interceptors return valid types:

AUR5007: Invalid Exponential Interval

Error Message: "An interval less than or equal to 1 second is not allowed when using the exponential retry strategy. Received: {interval}"

Cause: Exponential retry strategy configured with too short an interval.

Solution: Use an interval > 1000ms for exponential strategy:

AUR5008: Invalid Retry Strategy

Error Message: "Invalid retry strategy: {strategy}"

Cause: Provided an invalid retry strategy value.

Solution: Use valid retry strategy constants:

Error Handling Best Practices

Development vs Production

Cache Implementation Details

Cache Key Generation

The cache interceptor uses a simple but effective cache key strategy:

Key Components:

  • Prefix: 'au:interceptor:' - Identifies Aurelia cache entries

  • URL: Full request URL including query parameters

Important Notes:

  • Only the URL is used for cache keys

  • Request headers are NOT part of the cache key

  • Query parameters ARE part of the cache key (different query = different cache entry)

Cache Key Examples

Cache Header Marker

The cache interceptor uses a custom header to mark cached responses:

Usage:

Refresh Stale Immediate

When refreshStaleImmediate: true is configured, the cache interceptor sets up automatic refresh timers:

Behavior:

  1. When data is cached, a timer is set for the staleTime duration

  2. When the timer fires:

    • The cache entry is deleted

    • The original request is automatically re-fetched

    • The cache is updated with fresh data

    • CacheEvent.CacheStaleRefreshed event is published

Example:

Summary

This guide covered:

  • buildRequest(): Build requests without sending them

  • dispose(): Proper cleanup of HttpClient and interceptors

  • json(): Utility for JSON serialization with custom replacers

  • Error Codes: Complete AUR50XX error reference with solutions

  • Cache Details: Key generation, cache headers, and refresh behavior

These advanced features enable robust, production-ready HTTP client implementations with proper resource management and error handling.

Last updated

Was this helpful?