MethodSwitchingClient class
A client wrapper that dynamically routes requests between HTTP clients based on request type and content.
This client is useful when different requests should take different paths, such as AI requests, file uploads, streamed requests, or any request that should bypass interceptors.
It provides a single entry point that routes each request to the most appropriate underlying client at runtime.
The default routing behavior stays lightweight:
http.StreamedRequestuses the plain client- Gemini SSE-style requests use the plain client
- OpenAI and Anthropic streaming requests also use the plain client when
their JSON body contains
"stream": true
If you only need simple per-request routing, pass
useDefaultClientWhen at construction time. This callback has the highest
priority and is a convenient way to override the default routing behavior.
If you need finer-grained control, extend this class and override shouldUseDefaultClient. That lets you implement custom routing based on the request method, URL, headers, or body content.
This client is especially useful when:
- some requests should keep interceptor behavior
- some requests must bypass interceptors, such as long-lived connections, SSE, or streaming uploads
- different third-party APIs need different HTTP client paths
Example:
import 'dart:io';
import 'package:basic_http_interceptor/basic_http_interceptor.dart';
import 'package:googleai_dart/googleai_dart.dart';
import 'package:http/io_client.dart';
import 'package:logging/logging.dart';
final logger = Logger('google-ai');
final proxy = {
'no_proxy': 'localhost,127.0.0.1,::1',
'https_proxy': 'https://127.0.0.1:7890/',
'http_proxy': 'http://127.0.0.1:7890/',
'all_proxy': 'socks5://127.0.0.1:7891/',
};
final interceptedClient = interceptedClient(
proxy: proxy,
interceptors: [
InterceptorLogger(logger, true),
],
);
final defaultClient = IOClient(
HttpClient()
..findProxy = (url) =>
HttpClient.findProxyFromEnvironment(url, environment: proxy),
);
final client = MethodSwitchingClient(
interceptedClient,
defaultClient,
useDefaultClientWhen: (request) {
return request.url.host.contains('api.openai.com') ||
request.url.host.contains('api.anthropic.com');
},
);
final gaiClient = GoogleAIClient(
httpClient: client,
config: GoogleAIConfig.googleAI(
authProvider: ApiKeyProvider(apikey),
),
);
If you need even more control, extend this class and override shouldUseDefaultClient to fully customize the routing logic.
Constructors
- MethodSwitchingClient(Client _intercepted, Client _defaulted, {bool useDefaultClientWhen(BaseRequest request)?})
Properties
- defaultClient → Client
-
The plain client used for requests that should bypass interceptors.
no setter
- hashCode → int
-
The hash code for this object.
no setterinherited
- interceptedClient → Client
-
The client that applies interceptors.
no setter
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
close(
) → void - Closes the client and cleans up any resources associated with it.
-
delete(
Uri url, {Map< String, String> ? headers, Object? body, Encoding? encoding}) → Future<Response> -
Sends an HTTP DELETE request with the given headers to the given URL.
inherited
-
get(
Uri url, {Map< String, String> ? headers}) → Future<Response> -
Sends an HTTP GET request with the given headers to the given URL.
inherited
-
head(
Uri url, {Map< String, String> ? headers}) → Future<Response> -
Sends an HTTP HEAD request with the given headers to the given URL.
inherited
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
patch(
Uri url, {Map< String, String> ? headers, Object? body, Encoding? encoding}) → Future<Response> -
Sends an HTTP PATCH request with the given headers and body to the given
URL.
inherited
-
post(
Uri url, {Map< String, String> ? headers, Object? body, Encoding? encoding}) → Future<Response> -
Sends an HTTP POST request with the given headers and body to the given
URL.
inherited
-
put(
Uri url, {Map< String, String> ? headers, Object? body, Encoding? encoding}) → Future<Response> -
Sends an HTTP PUT request with the given headers and body to the given
URL.
inherited
-
read(
Uri url, {Map< String, String> ? headers}) → Future<String> -
Sends an HTTP GET request with the given headers to the given URL and
returns a Future that completes to the body of the response as a String.
inherited
-
readBytes(
Uri url, {Map< String, String> ? headers}) → Future<Uint8List> -
Sends an HTTP GET request with the given headers to the given URL and
returns a Future that completes to the body of the response as a list of
bytes.
inherited
-
send(
BaseRequest request) → Future< StreamedResponse> - Sends an HTTP request and asynchronously returns the response.
-
shouldUseDefaultClient(
BaseRequest request) → bool -
Returns
truewhenrequestshould be sent through defaultClient. -
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited