API Integration in Flutter using ‘dio’ Dependency: Step-by-Step Tutorial

Shahzaib Abid
4 min readFeb 15, 2024

API integration is a critical aspect of modern mobile app development, allowing applications to interact with external services and fetch data dynamically. In Flutter, a powerful framework for building cross-platform mobile apps, API integration is made easy with the help of the ‘dio’ package. In this comprehensive guide, we’ll walk you through the process of setting up API integration in Flutter app using the ‘dio’ dependency, from defining base configurations to making API requests with parameters.

➡️ Follow for more amazing tutorials.

Step 1: Setting Up a Flutter Project

To begin API integration in Flutter using the ‘dio’ dependency, you first need to set up a Flutter project.

  1. Creating a new Flutter project: Use the Flutter CLI or IDE to create a new Flutter project.
  2. Adding ‘dio’ dependency to the pubspec.yaml file: Open the pubspec.yaml file of your Flutter project and add the ‘dio’ dependency under the dependencies section.
dependencies:
flutter:
sdk: flutter
dio: ^5.4.0

Step 2: Create an API Service Class

Create an API Service class which will work as a template for all API calls.

class APIService {
APIService._singleton();
static final APIService instance = APIService._singleton();
}

Step 3: Define Base URL for Requests

  1. Add a method called baseUrl inside the APIService class.
  2. You can check if the app is running in debug mode using kDebugMode.
  3. If in debug mode, return the test server URL; otherwise, return the production server URL.
String get baseUrl {
if (kDebugMode) {
return 'test url';
}
return 'production-url';}

Step 4: Create Base Request Method

  1. Implement a method named request within the APIService class.
  2. This method should accept parameters such as endpoint, method, param, contentType, and formData.
  3. This method will serve as the base method for all API requests.
Future<Response> request(
String endpoint,
DioMethod method, {
Map<String, dynamic>? param,
String? contentType,
formData,
}) async {}

Step 5: Initialize Dio with Base Configuration

  1. Inside the request method, initialize a Dio instance with base configuration.
  2. Set the base URL using the baseUrl method.
  3. Configure headers, including the authorization header if a token is available.
final dio = Dio(
BaseOptions(
baseUrl: baseUrl,
contentType: contentType ?? Headers.formUrlEncodedContentType,
headers: {
HttpHeaders.authorizationHeader: 'Bearer $token’, // if needed },
),
);

Step 6: Making API Requests with Dio Methods

With the base configurations in place, making API requests becomes straightforward. Inside the request method, we use the initialized Dio instance to make requests based on the provided endpoint, HTTP method, and other parameters. A switch statement is used to handle different HTTP methods, ensuring flexibility and compatibility with various API endpoints.

  1. Create DioMethod enum with request types:
enum DioMethod { post, get, put, delete }

2. Now create switch statement with DioMethod enums:

switch (method) {
case DioMethod.post:
return dio.post(
endpoint,
data: param ?? formData,
);
case DioMethod.get:
return dio.get(
endpoint,
queryParameters: param,
);
case DioMethod.put:
return dio.put(
endpoint,
data: param ?? formData,
);
case DioMethod.delete:
return dio.delete(
endpoint,
data: param ?? formData,
);
default:
return dio.post(
endpoint,
data: param ?? formData,
);
}

Step 7: Making API Requests with APIService

  1. To make an API request, call the request method of the APIService instance with the required parameters: endpoint, HTTP method, parameters, content type, and form data.
  2. Handle the response appropriately, considering success and error cases.
Future<void> makeApiRequest(String email, String password) async {
try {
// Example of calling the request method with parameters
final response = await APIService.instance.request(
'/api/endpoint', // enter the endpoint for required API call
DioMethod.post,
param: {'email': email, 'password': password},
contentType: 'application/json',
);
// Handle the response
if (response.statusCode == 200) {
// Success: Process the response data
print('API call successful: ${response.data}');
} else {
// Error: Handle the error response
print('API call failed: ${response.statusMessage}');
}
} catch (e) {
// Error: Handle network errors
print('Network error occurred: $e');
}
}

Complete Code:

Making API integration in Flutter app easy for you, the complete code of the APIService class is below:

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';

enum DioMethod { post, get, put, delete }

class APIService {

APIService._singleton();

static final APIService instance = APIService._singleton();

String get baseUrl {

if (kDebugMode) {
return 'test url';
}

return 'production url';
}

Future<Response> request(
String endpoint,
DioMethod method, {
Map<String, dynamic>? param,
String? contentType,
formData,
}) async {
try {
final dio = Dio(
BaseOptions(
baseUrl: baseUrl,
contentType: contentType ?? Headers.formUrlEncodedContentType,
headers: {
HttpHeaders.authorizationHeader: 'Bearer $token',
},
),
);
switch (method) {
case DioMethod.post:
return dio.post(
endpoint,
data: param ?? formData,
);
case DioMethod.get:
return dio.get(
endpoint,
queryParameters: param,
);
case DioMethod.put:
return dio.put(
endpoint,
data: param ?? formData,
);
case DioMethod.delete:
return dio.delete(
endpoint,
data: param ?? formData,
);
default:
return dio.post(
endpoint,
data: param ?? formData,
);
}
} catch (e) {
throw Exception('Network error');
}
}
}

The complete code of how to make API call using APIService class is as below:

Future<void> makeApiRequest(String email, String password) async {
try {
final response = await APIService.instance.request(
'/api/endpoint',
DioMethod.post,
param: {'email': email, 'password': password},
contentType: 'application/json',
);
if (response.statusCode == 200) {
print('API call successful: ${response.data}');
} else {
print('API call failed: ${response.statusMessage}');
}
} catch (e) {
print('Network error occurred: $e');
}
}

Conclusion:

By following the steps outlined in this guide, you’ve learned API integration in Flutter app using the ‘dio’ package effectively. From defining base configurations to making API requests with parameters, each step is crucial for building robust and dynamic mobile applications. With API integration in Flutter app, it can interact with external services, fetch data dynamically, and provide users with a seamless and engaging experience.

Follow for more useful content of Flutter.

--

--