For the complete documentation index, see llms.txt. This page is also available as Markdown.

FAQ

*.chopper.dart not found ?

If you have this error, you probably forgot to run code generation. To do that, run the following command in your shell.

dart run build_runner build

It will generate the code that actually does the HTTP request (YOUR_FILE.chopper.dart). If you wish to update the code automatically when you change your definition, run the watch command.

dart run build_runner watch

How to set a connection timeout?

For Dart VM and Flutter mobile/desktop apps, provide an IOClient configured with a dart:io HttpClient. This controls the socket connection timeout, not the full request deadline.

import 'package:http/io_client.dart' as http;
import 'dart:io';

final chopper = ChopperClient(
  client: http.IOClient(
    HttpClient()..connectionTimeout = const Duration(seconds: 60),
  ),
);

Use Chopper's per-request timeout support when you need to abort a slow request after a deadline.

How to set a timeout?

Chopper supports two per‑request ways to stop a slow request:

  1. Hard timeout (auto‑abort) — add a timeout: to your endpoint annotation. The generated code creates an internal abort trigger and cancels the underlying HTTP request when the deadline expires. The error you get is a TimeoutException.

  1. Manual cancellation — @AbortTrigger

Accept an @AbortTrigger parameter and pass a Future<void> (usually from a Completer<void>). When that future completes, Chopper aborts the underlying HTTP request (using http's abortable support) and a RequestAbortedException is thrown — mirroring the HTTP package example.

Usage:

Rules & behavior

  • Don’t combine a method timeout: and an @AbortTrigger param on the same endpoint; generation will fail (pick one mechanism).

  • Timeouts abort the HTTP request, they are not just Future.timeout(...) wrappers. This uses the new abortable requests in http and stops uploads/streams mid‑flight.

  • Manual aborts surface as RequestAbortedException; timeouts surface as TimeoutException with a clear message.

  • Chopper 8.5+ depends on http versions with abortable request support and requires Dart SDK 3.9 or newer.

Add query parameter to all requests

Possible using an interceptor.

GZip converter example

You can use converters for modifying requests and responses. For example, to use GZip for post request you can write something like this:

Runtime baseUrl change

You may need to change the base URL of your network calls during runtime, for example, if you have to use different servers or routes dynamically in your app in case of a "regular" or a "paid" user. You can store the current server base URL in your SharedPreferences (encrypt/decrypt it if needed) and use it in an interceptor like this:

Mock ChopperClient for testing

Chopper is built on top of http package.

So, one can just use the mocking API of the HTTP package. See the documentation for the http.testing library and for the MockClient class.

Also, you can follow this code by ozburo:

Use HTTPS certificate

Chopper is built on top of http package and you can override the inner http client. Only bypass certificate validation for local development or controlled testing.

Authorized HTTP requests

Basically, the algorithm goes like this (credits to stewemetal):

Add the authentication token to the request (by "Authorization" header, for example) -> try the request -> if it fails use the refresh token to get a new auth token -> if that succeeds, save the auth token and retry the original request with it if the refresh token is not valid anymore, drop the session (and navigate to the login screen, for example)

Simple code example:

The actual implementation of the algorithm above may vary based on how the backend API - more precisely the login and session handling - of your app looks like. Breaking out of the authentication flow/interceptor can be achieved in multiple ways. For example, you can throw an exception or use a service that handles navigation. See interceptors for more info.

Authorized HTTP requests using the special Authenticator interceptor

Similar to OkHTTP's authenticator, the idea here is to provide a reactive authentication in the event that an auth challenge is raised. It returns a nullable Request that contains a possible update to the original Request to satisfy the authentication challenge.

Decoding JSON using Isolates

Sometimes you want to decode JSON outside the main thread in order to reduce janking. In this example we're going to go even further and implement a Worker Pool using Squadron which can dynamically spawn a maximum number of Workers as they become needed.

Install the dependencies

Write a JSON decode service

We'll leverage squadron_builder and the power of code generation.

Extracted from the full example here.

Write a custom JsonConverter

Using json_serializable we'll create a JsonConverter which works with or without a WorkerPool.

When JsonConverter decodes directly into typed JSON collections, such as Response<List<double>> or Response<Map<String, double>>, Chopper can report the list index or map key that failed conversion. Model fields are decoded by your serializer factory, so enable checked: true for json_serializable to get CheckedFromJsonException errors with field context from generated fromJson methods.

Extracted from the full example here.

Code generation

It goes without saying that running the code generation is a pre-requisite at this stage

Changing the default extension of the generated files

If you want to change the default extension of the generated files from .chopper.dart to something else, you can do so by adding the following to your build.yaml file:

Configure a WorkerPool and run the example

The full example can be found here.

Further reading

This barely scratches the surface. If you want to know more about squadron and squadron_builder make sure to head over to their respective repositories.

David Markey, the author of squadron, was kind enough as to provide us with an excellent Flutter example using both packages.

How to use Chopper with Injectable

Create a module for your ChopperClient

Define a module for your ChopperClient. You can use the @lazySingleton (or other type if preferred) annotation to make sure that only one is created.

Create ChopperService with Injectable

Define your ChopperService as usual. Annotate the class with @lazySingleton (or other type if preferred) and use the @factoryMethod annotation to specify the factory method for the service. This would normally be the static create method.

Last updated