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_value or json_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 build

It 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, AuthApiService etc.
  • Keep API calls out of UI
  • Great for unit testing and mocking services
  • Use with Riverpod, Bloc, or Provider easily

πŸ’‘ Pro Tips

  • Combine with freezed for immutable models
  • Use built_value for powerful serialization
  • Customize with your own Converter class
  • 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!