Tired of writing boilerplate code for HTTP requests? Want a more structured, testable, and maintainable way to call APIs in Flutter? Say hello to chopper β the Retrofit-style HTTP client built specifically for Dart and Flutter developers.
π― Why Use chopper?
- β Clean separation of concerns
- β Service-based architecture
- β Strongly-typed requests and responses
- β Interceptors for requests and responses
- β Custom converters (e.g., JSON, XML)
- β
Works great with
built_valueorjson_serializable - β Reusable and testable API layer
π οΈ Installation
Add this to your pubspec.yaml:
dependencies:
chopper: ^6.1.2
build_runner: ^2.4.7
chopper_generator: ^6.1.2
json_annotation: ^4.9.0π§ Step-by-Step Setup
1. Define a Chopper API Service
import 'package:chopper/chopper.dart';
part 'post_api_service.chopper.dart';
@ChopperApi()
abstract class PostApiService extends ChopperService {
@Get(path: '/posts/{id}')
Future<Response> getPost(@Path('id') int id);
static PostApiService create() {
final client = ChopperClient(
baseUrl: Uri.parse('https://jsonplaceholder.typicode.com'),
services: [_$PostApiService()],
converter: JsonConverter(),
);
return _$PostApiService(client);
}
}2. Generate Code
Run the build_runner command:
flutter pub run build_runner buildIt creates the post_api_service.chopper.dart file, containing the generated boilerplate code.
π² Using the Service in Your App
final postService = PostApiService.create();
final response = await postService.getPost(1);
if (response.isSuccessful) {
print(response.body);
} else {
print('Error: ${response.statusCode}');
}π§° Add Interceptors (e.g., Logging)
final client = ChopperClient(
baseUrl: Uri.parse('https://jsonplaceholder.typicode.com'),
services: [_$PostApiService()],
converter: JsonConverter(),
interceptors: [
HttpLoggingInterceptor(),
(Request request) async => request.copyWith(headers: {
...request.headers,
'Authorization': 'Bearer your_token_here'
}),
],
);π§ͺ Testable and Maintainable
- Define multiple services like
UserApiService,AuthApiServiceetc. - Keep API calls out of UI
- Great for unit testing and mocking services
- Use with Riverpod, Bloc, or Provider easily
π‘ Pro Tips
- Combine with
freezedfor immutable models - Use
built_valuefor powerful serialization - Customize with your own
Converterclass - Integrate logging, retry, and offline caching manually
π Ideal For:
- Projects needing clean, scalable API layers
- Apps with RESTful APIs and strong model structure
- Developers who prefer generated code for reliability
- Test-driven development workflows
π§ Final Thoughts
chopper brings the best of Retrofit-style networking into Flutter. With service classes, auto-generated request handling, and interceptors, your API layer becomes modular, clean, and easy to maintain β especially as your app grows.
"Clean code starts at the network layer. Chopper lets you build API services like a pro."
If you found this story helpful, you can support me at Buy Me a Coffee!