Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 57 additions & 12 deletions pkgs/http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ try {

> [!TIP]
> For detailed background information and practical usage examples, see:
>
> - [Dart Development: Fetch data from the internet](https://dart.dev/tutorials/server/fetch-data)
> - [Flutter Cookbook: Fetch data from the internet](https://docs.flutter.dev/cookbook/networking/fetch-data)
> - [The Flutter HTTP example application][flutterhttpexample]
Expand Down Expand Up @@ -83,6 +84,52 @@ class UserAgentClient extends http.BaseClient {
}
```

## Testing

For better testability, especially in Flutter applications, it's recommended to use a [Client][] instance rather than the top-level functions like `http.get()` or `http.post()`. This approach makes it easier to mock HTTP requests in your tests.

```dart
// Instead of using static methods (harder to test):
// var response = await http.get(Uri.https('example.com', 'data.json'));

// Use a Client instance (easier to test):
class DataService {
final http.Client client;

DataService({http.Client? client}) : client = client ?? http.Client();

Future<String> fetchData() async {
var response = await client.get(Uri.https('example.com', 'data.json'));
return response.body;
}
}
```

In your tests, you can easily mock the HTTP client:

```dart
import 'package:http/testing.dart';
import 'package:test/test.dart';

void main() {
test('fetchData returns expected data', () async {
final mockClient = MockClient((request) async {
return http.Response('{"key": "value"}', 200);
});

final dataService = DataService(client: mockClient);
final result = await dataService.fetchData();

expect(result, '{"key": "value"}');
});
}
```

> [!TIP]
> For more detailed testing guidance, see the
> [Flutter testing cookbook](https://docs.flutter.dev/cookbook/testing/unit/mocking)
> which demonstrates best practices for mocking HTTP requests.

## Retrying requests

`package:http/retry.dart` provides a class [`RetryClient`][RetryClient] to wrap
Expand Down Expand Up @@ -198,7 +245,6 @@ Future<void> main() async {
[aborttrigger]: https://pub.dev/documentation/http/latest/http/Abortable/abortTrigger.html
[requestabortedexception]: https://pub.dev/documentation/http/latest/http/RequestAbortedException-class.html


## Choosing an implementation

There are multiple implementations of the `package:http` [`Client`][client] interface. By default, `package:http` uses [`BrowserClient`][browserclient] on the web and [`IOClient`][ioclient] on all other platforms. You can choose a different [`Client`][client] implementation based on the needs of your application.
Expand All @@ -208,13 +254,13 @@ for a few lines of [configuration](#2-configure-the-http-client).

Some well-supported implementations are:

| Implementation | Supported Platforms | SDK | Caching | HTTP3/QUIC | Platform Native |
| -------------- | ------------------- | ----| ------- | ---------- | --------------- |
| `package:http` — [`IOClient`][ioclient] | Android, iOS, Linux, macOS, Windows | Dart, Flutter | ❌ | ❌ | ❌ |
| `package:http` — [`BrowserClient`][browserclient] | Web | Dart, Flutter | ― | ✅︎ | ✅︎ | Dart, Flutter |
| [`package:cupertino_http`][cupertinohttp] — [`CupertinoClient`][cupertinoclient] | iOS, macOS | Flutter | ✅︎ | ✅︎ | ✅︎ |
| [`package:cronet_http`][cronethttp] — [`CronetClient`][cronetclient] | Android | Flutter | ✅︎ | ✅︎ | ― |
| [`package:fetch_client`][fetch] — [`FetchClient`][fetchclient] | Web | Dart, Flutter | ✅︎ | ✅︎ | ✅︎ |
| Implementation | Supported Platforms | SDK | Caching | HTTP3/QUIC | Platform Native |
| -------------------------------------------------------------------------------- | ----------------------------------- | ------------- | ------- | ---------- | --------------- |
| `package:http` — [`IOClient`][ioclient] | Android, iOS, Linux, macOS, Windows | Dart, Flutter | ❌ | ❌ | ❌ |
| `package:http` — [`BrowserClient`][browserclient] | Web | Dart, Flutter | ― | ✅︎ | ✅︎ |
| [`package:cupertino_http`][cupertinohttp] — [`CupertinoClient`][cupertinoclient] | iOS, macOS | Flutter | ✅︎ | ✅︎ | ✅︎ |
| [`package:cronet_http`][cronethttp] — [`CronetClient`][cronetclient] | Android | Flutter | ✅︎ | ✅︎ | ― |
| [`package:fetch_client`][fetch] — [`FetchClient`][fetchclient] | Web | Dart, Flutter | ✅︎ | ✅︎ | ✅︎ |

> [!TIP]
> If you are writing a Dart package or Flutter plugin that uses
Expand All @@ -233,6 +279,7 @@ Some well-supported implementations are:
## Configuration

To use an HTTP client implementation other than the default, you must:

1. Add the HTTP client as a dependency.
2. Configure the HTTP client.
3. Connect the HTTP client to the code that uses it.
Expand Down Expand Up @@ -284,8 +331,7 @@ Client httpClient() {
}
```

> [!TIP]
> [The Flutter HTTP example application][flutterhttpexample] demonstrates
> [!TIP] > [The Flutter HTTP example application][flutterhttpexample] demonstrates
> configuration best practices.

#### Supporting browser and native
Expand Down Expand Up @@ -339,8 +385,7 @@ void main() {
When using the Flutter SDK, you can use a one of many
[state management approaches][flutterstatemanagement].

> [!TIP]
> [The Flutter HTTP example application][flutterhttpexample] demonstrates
> [!TIP] > [The Flutter HTTP example application][flutterhttpexample] demonstrates
> how to make the configured [`Client`][client] available using
> [`package:provider`][provider] and
> [`package:http_image_provider`][http_image_provider].
Expand Down