Mastering API integration in Flutter with Chopper (2024)

Mastering API integration in Flutter with Chopper (1)

Published in

FAUN — Developer Community 🐾

·

6 min read

·

Apr 1, 2023

--

In Flutter there are various packages available for integrating APIs, such as Dio, Retrofit, HTTP, and many more. In this blog, we will try to learn about one of the most efficient packages for integrating APIs called Chopper.

Mastering API integration in Flutter with Chopper (3)

Chopper is a package for making API calls in Flutter apps.

Chopper generates code that makes it easy to define API endpoints as Dart functions with strongly typed request and response bodies. It also supports interceptors for adding headers, logging requests and responses, and caching responses.

Chopper is built on top of the http package, which means it supports all of the same HTTP methods (GET, POST, PUT, DELETE, etc.) and options as the http package. However, Chopper makes it easier to write clean, organized code for making API calls in Flutter apps.

There are several reasons why you might want to use Chopper instead of other packages for making API calls in Flutter:

  1. Strongly-typed requests and responses: Chopper generates code that defines Dart classes for your API requests and responses, which makes it easy to work with data in a type-safe manner.
  2. Interceptors: Chopper supports interceptors, which can be used to add headers to requests, log requests and responses, and more.
  3. Easy to use: Chopper provides a simple and intuitive API for making API calls, which can make it easier for developers to get started and build their apps quickly.

Overall, Chopper is a powerful and flexible package for making API calls in Flutter, and it can be a great choice for developers who value strong typing, serialization, and ease of use.

Add the Chopper package to your pubspec.yaml file:

dependencies:
chopper: ^<latest version>

dev_dependencies:
build_runner: ^1.12.2
chopper_generator: ^<latest version>

Generate the Chopper code for your API

Chopper uses code generation to create API service classes based on the API specification. To generate the code, you’ll need to define an interface for your API using annotations from the chopper package. Here's an example:

import 'package:chopper/chopper.dart';

part 'AuthChopperService.chopper.dart';

@ChopperApi()
abstract class AuthChopperService extends ChopperService {

static AuthChopperService create({ChopperClient? client}) => _$AuthChopperService(client);

@Post(path:APIEndpoints.loginUrl)
Future<Response<LoginResponseEntity>> loginUser(
@body LoginRequest loginRequest);

@Post(path:APIEndpoints.registerUrl)
Future<Response<LoginResponseEntity>> registerUser(
@body RegisterUserRequest registerUser);
}

This code defines a Chopper service interface called AuthChopperService using the @ChopperApi() annotation.

The interface extends ChopperService which provides a set of methods to interact with an API.

AuthChopperService has a single method called loginUser which is decorated with the @Post annotation, indicating that it sends a HTTP POST request to the specified URL. The URL path is defined in the annotation with "login url".

The loginUser method takes a single parameter loginRequest, which is a Map<String,dynamic> object that contains the login request data.

The return type of loginUser is a Future<Response<LoginResponseEntity>>. This means that the method returns a Future object that will eventually contain a Response object, which in turn contains a LoginResponseEntity object.

LoginResponseEntity is a custom Dart class that represents the response data for the login API call.

The static create method is a factory method that creates an instance of AuthChopperService with an optional ChopperClient instance.

Finally, the AuthChopperService interface is defined in a separate file called AuthChopperService.chopper.dart, which is generated by Chopper when the app is built. This file contains the implementation of the service interface that makes the HTTP requests to the server. The implementation is generated based on the annotations and method signatures defined in the AuthChopperService interface.

Once you’ve defined your API interface, you can generate the Chopper code by running the following command in your terminal:

flutter pub run build_runner build

This command will generate a new file called my_api_service.chopper.dart that contains the Chopper service class for your API.

Create a Chopper client class

To use the Chopper services which we created, we have to get the instance of ChopperClient. For this we will use the following code.


class AppChopperClient {
late ChopperClient _client;
AppChopperClient() {
createChopperClient();
}

T getChopperService<T extends ChopperService>() {
return _client.getService<T>();
}

void createChopperClient() {
_client = ChopperClient(
baseUrl: Uri.parse("<Base url>"),
services: [
AuthChopperService.create(),

],
interceptors: [
RequestLogger(),
ResponseLogger(),
ApplyHeaderInterceptor(),
],
converter: const JsonToTypeConverter(jsonConvertorMap: {
LoginResponseEntity: LoginResponseEntity.fromJson,
}),
errorConverter: const JsonToTypeConverter(
jsonConvertorMap: {GeneralErrorModel: GeneralErrorModel.fromJson}));
}
}

TheAppChopperClient the class that uses the Chopper package in a Flutter app to create a Chopper client and Chopper service instances.

The class has a single private field _client of type ChopperClient, which is initialized in the constructor using the createChopperClient() method. The method sets up the Chopper client with the following properties:

  • baseUrl: A string that specifies the base URL for the API.
  • services: A list of Chopper service classes, which are defined using the create() method of the corresponding service interface. In this example, there is only one service class, AuthChopperService.
  • interceptors: A list of interceptors that can be used to modify the request or response before they are sent or received. In this example, there are three interceptors: RequestLogger, ResponseLogger, and ApplyHeaderInterceptor. We will look at each interceptor in detail in some other blog.
  • converter: An instance of a Converter subclass that is used to serialize and deserialize JSON data. In this example, the JsonToTypeConverter class used which is completely written by me, that maps JSON data to Dart classes using a map of converter functions.
  • errorConverter: An instance of a Converter subclass that is used to convert error responses to Dart objects. In this example, the JsonToTypeConverter class is used again, with a map that maps error responses to GeneralErrorModel instances.

The class also defines a generic method getChopperService<T>() that returns an instance of a Chopper service based on the type parameter T. This method uses the _client field to create and return an instance of the requested Chopper service.

Before we use it, we require to use some dependency injection method for initializing ChopperClient and our AppChopperClient() class. One of the way to achieve it is using Bindings in GetX.

import 'package:get/get.dart';

class AuthBinding implements Bindings{
@override
void dependencies() {
Get.lazyPut(() => AppChopperClient());
}

}

Use the Chopper service to make API requests: Once you’ve created the Chopper client, you can use your Chopper service class to make API requests. Here’s an example:

final response = await Get.find<AppChopperClient>().getChopperService<AuthChopperService>ChopperClient>();
if (response.isSuccessful) {
final loginResponse = response.body;
// do something with the posts...
} else {
final loginError = response.error;
// handle the error...
}

This code uses the Chopper package to make API calls in a Flutter app. We first get an instance of the AppChopperClient class and call its getChopperService() method to get an instance of the AuthChopperService class, which defines API endpoints for authentication.

We call methods from the AuthChopperService class to send requests to the server. The response is returned in a Response object, which we check for success using the isSuccessful property. We can access the response body using the body property or the error using the error property.

And that’s it! With these steps, you should be able to use the Chopper package to make API calls in your Flutter app.

To get code for three interceptors: RequestLogger, ResponseLogger, and ApplyHeaderInterceptor and convertorJsonToTypeConverteryou can mail me on my email id: mustisid786@gmail.com

Thank you for reading! If you found this helpful, please give it a clap and share it with your friends and colleagues.

Mastering API integration in Flutter with Chopper (4)

👋 If you find this helpful, please click the clap 👏 button below a few times to show your support for the author 👇

🚀Join FAUN Developer Community & Get Similar Stories in your Inbox Each Week

Mastering API integration in Flutter with Chopper (2024)

References

Top Articles
Latest Posts
Article information

Author: Rubie Ullrich

Last Updated:

Views: 6500

Rating: 4.1 / 5 (52 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Rubie Ullrich

Birthday: 1998-02-02

Address: 743 Stoltenberg Center, Genovevaville, NJ 59925-3119

Phone: +2202978377583

Job: Administration Engineer

Hobby: Surfing, Sailing, Listening to music, Web surfing, Kitesurfing, Geocaching, Backpacking

Introduction: My name is Rubie Ullrich, I am a enthusiastic, perfect, tender, vivacious, talented, famous, delightful person who loves writing and wants to share my knowledge and understanding with you.