Custom Fetch Functions

View Source

AshTypescript uses the standard Fetch API by default. You can customize requests using fetchOptions or replace the fetch implementation entirely with customFetch.

Using fetchOptions

For simple customization like timeouts or cache control, use the fetchOptions parameter:

import { listTodos } from './ash_rpc';

// Add timeout and cache control
const todos = await listTodos({
  fields: ["id", "title"],
  fetchOptions: {
    signal: AbortSignal.timeout(5000),
    cache: 'no-cache',
    credentials: 'include'
  }
});

// Cancellable request
const controller = new AbortController();
const todosPromise = listTodos({
  fields: ["id", "title"],
  fetchOptions: {
    signal: controller.signal
  }
});

controller.abort(); // Cancel the request

See the MDN Fetch API documentation for all available options.

Custom Fetch Functions

Use customFetch when:

  • Your JS framework provides a custom fetch function you need to use
  • You want to use axios or another HTTP client instead of fetch

Framework-Provided Fetch

Some frameworks provide their own fetch function with built-in features. Pass it directly:

import { frameworkFetch } from 'your-framework';
import { listTodos } from './ash_rpc';

const todos = await listTodos({
  fields: ["id", "title"],
  customFetch: frameworkFetch
});

Using Axios

Create an adapter that wraps axios to match the fetch interface:

import axios from 'axios';
import { listTodos } from './ash_rpc';

const axiosAdapter = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
  const url = typeof input === 'string' ? input : input.toString();

  try {
    const response = await axios({
      url,
      method: init?.method || 'GET',
      headers: init?.headers as Record<string, string>,
      data: init?.body,
      validateStatus: () => true
    });

    return new Response(JSON.stringify(response.data), {
      status: response.status,
      statusText: response.statusText,
      headers: new Headers(response.headers as Record<string, string>)
    });
  } catch (error: any) {
    if (error.response) {
      return new Response(JSON.stringify(error.response.data), {
        status: error.response.status,
        statusText: error.response.statusText
      });
    }
    throw error;
  }
};

const todos = await listTodos({
  fields: ["id", "title"],
  customFetch: axiosAdapter
});

Global Configuration

For settings that apply to all requests (authentication, logging, etc.), use Lifecycle Hooks instead of passing customFetch to every call.

Next Steps