Effortless API Integration in Flutter with DIO: Everything You Need to Know
Hello Devs, Today, I want to chat with you about Dio, a super powerful networking package used in Flutter for fetching APIs from the server. You might already know that there are other packages available for network calls, but what makes Dio stand out is its extra features like interceptors, the ability to abort and cancel requests, custom adapters, transformers, and more. If you're someone who's shifted from Android to Flutter, you'll find Dio to be quite similar to Retrofit. Let's dive in and learn more about this awesome tool together!
Great, let's work on installing the Dio package on your project together!
Package Installation
There are two to-install packages in Flutter:
Using Command
Directly add the package to your Pubspec.yaml file
Using Command
Run this command on your vs code terminal:
For Dart:
$ dart pub add dio
For Flutter:
$ flutter pub add dio
Direct add package on your Pubspec.yamp file
dependencies:
dio: ^5.4.1
Remember to always run this dart pub get
command after adding a package to your project. This step is crucial to ensure the smooth and error-free functioning of your project and should not be overlooked.
Awesome! Your Dio package installation is all done now. Let's take the next step and create an init class for Dio where you can easily configure your Dio code.
Dio config class
class DioConfig {
Dio init() {
Dio dio = Dio();
dio.options.baseUrl = 'https://jsonplaceholder.typicode.com'; // Replace with your base URL
dio.interceptors.add(LogInterceptor(responseBody: true));
dio.transformer = MyTransformer();
dio.httpClientAdapter = MyHttpClientAdapter();
return dio;
}
}
// Custom transformer
class MyTransformer extends DefaultTransformer {
@override
Future<String> transformResponse(RequestOptions options, ResponseBody response) async {
return response.toString(); // Custom transformation, in this case, just convert response to string
}
}
// Custom HttpClientAdapter
class MyHttpClientAdapter extends HttpClientAdapter {
@override
Future<ResponseBody> fetch(RequestOptions options, Stream<List<int>> requestStream, Future cancelFuture) async {
final uri = options.uri;
final client = HttpClient();
final request = await client.getUrl(uri);
// Optionally, you can modify the request headers, timeouts, etc. here
final response = await request.close();
final responseBody = await response.transform(Utf8Decoder()).join();
return ResponseBody.fromString(responseBody, 200);
}
@override
void close({bool force = false}) {}
}
The following is a brief overview of the DioConfig class that has been implemented in the code.
It contains a method
init()
that initializes and configures the Dio instance.Inside the method, a new Dio instance is created.
The base URL for requests is set using
dio.options.baseUrl
.An interceptor is added using
dio.interceptors.add(LogInterceptor())
to log HTTP request and response data.Custom transformer and HTTP client adapter are set using
dio.transformer
anddio.httpClientAdapter
respectively.
As you see I created one MyTransformer class. The purpose of this class is to allow customization of the response transformation process. Here is a short description of this class
Extends
DefaultTransformer
class provided by Dio.Overrides the
transformResponse()
method to customize how responses are transformed.In this example, it simply converts the response body to a string.
There is one more class that I created on this code called MyHttpClientAdapter. It helps with handling HTTP requests and responses. Here is a short description of this class
Extends
HttpClientAdapter
provided by Dio.Overrides the
fetch()
method that is responsible for making HTTP requests.Inside
fetch()
, it creates a newHttpClient
instance, sends the request, and retrieves the response.Optionally, it allows for modification of request headers, timeouts, etc.
The response body is decoded into a string using UTF-8 decoding and returned as an
ResponseBody
object.
Overall, this code demonstrates how to configure Dio with custom behaviour such as logging, transforming responses, and customizing the basic HTTP client adapter.
Let us now proceed to the main class where we can invoke the DioConfig class to initiate API requests. We will be utilizing the DioConfig class in this section to facilitate communication with the API.
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Dio Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late Dio _dio;
@override
void initState() {
super.initState();
_dio = DioConfig().init();
}
@override
void dispose() {
_dio.close();
super.dispose();
}
Future<void> fetchData() async {
try {
final response = await _dio.get('/posts/1');
print(response.data);
} catch (e) {
print(e.toString());
}
}
void cancelRequest() {
_dio.clear();
print('Request canceled.');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dio Advanced Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: fetchData,
child: Text('Fetch Data'),
),
ElevatedButton(
onPressed: cancelRequest,
child: Text('Cancel Request'),
),
],
),
),
);
}
}
It's time to provide a concise explanation of this code block. Let me give you a brief description of what it does.
Application Setup: The
main()
function initializes the Flutter application by runningMyApp()
.MyApp Widget:
MyApp
is a Stateless widget that sets up the basic structure of the application. It uses MaterialApp to define the app's title, theme, and home page.MyHomePage Widget:
MyHomePage
is a Stateful widget that represents the home page of the application. It contains two main functionalities:Initialization: In the
initState()
method, Dio is initialized usingDioConfig().init()
. This configures Dio with base URLs and interceptors.Request Handling: The
fetchData()
method makes a GET request to '/posts/1' using Dio and prints the response data. ThecancelRequest()
method cancels any ongoing requests.
DioConfig: This class provides a convenient way to initialize Dio with custom configurations such as base URLs, interceptors, etc. It is used in
initState()
ofMyHomePage
to set up the Dio instance.
We've wrapped up the blog post now. Just wanted to remind you to aim for clean and organized code when you're working on your projects. Remember, writing good code is key to success!
Connect with Me:
Hey there! If you enjoyed reading this blog and found it informative, why not connect with me on LinkedIn? ๐ You can also follow my Instagram page for more mobile development-related content. ๐ฒ๐จโ๐ป Letโs stay connected, share knowledge and have some fun in the exciting world of app development! ๐
Subscribe to my newsletter
Read articles from Mayursinh Parmar directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Mayursinh Parmar
Mayursinh Parmar
๐ฑMobile App Developer | Android & Flutter ๐๐ก Passionate about creating intuitive and engaging apps ๐ญโจ Letโs shape the future of mobile technology!