configure static method

void configure({
  1. required Future<String?> getToken(),
  2. required Future<bool> onTokenRefresh(),
  3. void onRefreshFailed()?,
  4. Map<String, String> headerBuilder(
    1. String token
    )?,
  5. bool bypassConnectivityCheck = false,
  6. Duration refreshTimeout = const Duration(seconds: 30),
  7. ApiLogOptions logging = const ApiLogOptions(),
})

Configures ApiServices with token-based authentication and automatic token refresh on 401 responses.

Call once at app startup before instance. Calling it again replaces the singleton (useful for re-login after logout).

Parameters:

  • getToken — returns the current bearer token from storage. Called before every request to attach the Authorization header.

  • onTokenRefresh — performs the actual refresh (e.g. calls /auth/refresh and saves the new token). Return true on success, false on failure.

  • onRefreshFailed — called when refresh returns false or throws. Use this to log the user out or navigate to the login screen.

  • headerBuilder — customises the auth headers built from the token. Omit to use the default {'Authorization': 'Bearer <token>'}.

  • bypassConnectivityCheck — when true, skips the pre-flight internet connectivity check. Use in staging/internal environments where external connectivity probes fail because of proxies or firewalls. See also setConnectivityCheck.

  • refreshTimeout — how long a request that 401s while another refresh is already in flight will wait for that refresh before giving up and failing with the original error. Defaults to 30 seconds.

  • logging — what the console logger prints (request line, headers, bodies, errors, width, compactness, and where the lines go). Pass ApiLogOptions.disabled() to turn logging off. Only affects non-release builds — nothing is logged in release regardless. See ApiLogOptions and setLogging.

Example:

// main_production.dart
ApiServices.configure(
  getToken: () async => GetToken.getToken(),
  onTokenRefresh: AuthSessionService.refreshToken,
  onRefreshFailed: AuthSessionService.onSessionExpired,
);

// main_staging.dart — internal network with proxy
ApiServices.configure(
  getToken: () async => GetToken.getToken(),
  onTokenRefresh: AuthSessionService.refreshToken,
  onRefreshFailed: AuthSessionService.onSessionExpired,
  bypassConnectivityCheck: true,
);

Implementation

static void configure({
  required Future<String?> Function() getToken,
  required Future<bool> Function() onTokenRefresh,
  void Function()? onRefreshFailed,
  Map<String, String> Function(String token)? headerBuilder,
  bool bypassConnectivityCheck = false,
  Duration refreshTimeout = const Duration(seconds: 30),
  ApiLogOptions logging = const ApiLogOptions(),
}) {
  _bypassConnectivityCheck = bypassConnectivityCheck;
  _logOptions = logging;
  final dio = DioFactory().getDio(logOptions: logging);
  dio.interceptors.add(TokenRefreshInterceptor(
    dio: dio,
    getToken: getToken,
    onTokenRefresh: onTokenRefresh,
    onRefreshFailed: onRefreshFailed,
    headerBuilder: headerBuilder,
    refreshTimeout: refreshTimeout,
  ));
  _instance = ApiServicesImplementation.instanceFor(dio: dio);
}