Skip to content

karanpadaliya/Learn-Retrofit-Dio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

24 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸš€ Flutter Retrofit + Dio API Integration Guide

This project demonstrates how to use Retrofit and Dio in a Flutter app for making clean and scalable API requests. This guide is beginner-friendly and covers all necessary steps including GET, POST, PUT, DELETE, PATCH, and Query Parameters usage.


πŸ”§ Step 1: Add Dependencies

Add the generator to your dev dependencies
dependencies:
  retrofit: ^x.x.x
  dio: ^x.x.x

dev_dependencies:
  retrofit_generator: ^x.x.x
  build_runner: ^x.x.x

πŸ“ Step 2: Create api_services.dart

import 'package:dio/dio.dart';
import 'package:learn_retrofit_dio/models/models.dart';
import 'package:retrofit/retrofit.dart';
import '../models/fetch_user_model/fetch_all_user_list_model.dart';

part 'api_services.g.dart';

@RestApi(baseUrl: 'https://reqres.in/')
abstract class ApiServices {
  factory ApiServices(Dio dio, {String? baseUrl}) = _ApiServices;

  // Fetch all user
  @GET('api/users?page=2')
  Future<UserList> getUserList();

  // Fetch single user
  @GET('api/users/{id}')
  Future<SingleUserModel> getSingleUser(
    @Header('x-api-key') String apiKey,
    @Path('id') String id,
  );

  // Create a user
  @POST('api/users')
  Future<CreateUserShowModel> createUser(
    @Header('x-api-key') String apiKey,
    @Body() CreateUserRequestModel request,
  );
}

🧠 Step 3: Create Model & Injection

πŸ“Œ 1. Generate Model

Use this tool to convert JSON to Dart: Json to Dart Converter

πŸ“Œ 2. Create injection.dart

import 'package:dio/dio.dart';
import 'package:learn_retrofit_dio/network/api_services.dart';

final apiServices = ApiServices(Dio());

βš™οΈ Step 4: Generate .g.dart File

dart pub run build_runner build

πŸ–₯️ Step 5: Display API Data in Flutter

import 'package:flutter/material.dart';
import '../models/fetch_user_model/fetch_all_user_list_model.dart';
import '/config/config.dart';
import 'widget/widget.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  UserList userList = UserList();
  bool isLoading = true;
  UserRepository userRepo = UserRepository.userRepository;

  @override
  void initState() {
    super.initState();
    fetchUsers();
  }

  Future<void> fetchUsers() async {
    final fetchedList = await userRepo.fetchAllUserList();
    setState(() {
      userList = fetchedList;
      isLoading = false;
    });
  }

  void showUserDetails(String userId) {
    showDialog(
      context: context,
      builder: (context) => UserDetailsShowDialog(userId: userId),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Retrofit API')),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Expanded(
              child:
                  isLoading
                      ? Center(child: CircularProgressIndicator())
                      : RefreshIndicator(
                        onRefresh: userRepo.fetchAllUserList,
                        child: ListView.builder(
                          itemCount: userList.data?.length ?? 0,
                          itemBuilder: (context, index) {
                            final user = userList.data![index];
                            return InkWell(
                              onTap: () {
                                showUserDetails(user.id.toString());
                              },
                              child: ListTile(
                                leading: CircleAvatar(
                                  backgroundImage: NetworkImage(
                                    user.avatar.toString(),
                                  ),
                                ),
                                title: Text(user.firstName.toString()),
                                subtitle: Text(user.email.toString()),
                              ),
                            );
                          },
                        ),
                      ),
            ),

            Row(
              mainAxisSize: MainAxisSize.min,
              children: [
                Spacer(),
                ElevatedButton(
                  onPressed: () {
                    showDialog(
                      context: context,
                      builder: (context) => CreateUserDialog(),
                    );
                  },
                  child: Text('Create User'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

πŸ“‘ API Services Examples

βœ… 1. GET Request (List of Users)

@GET('api/users')
Future UserList getUserList(@Query('page') int page);

// Usage:
final userList = await apiServices.getUserList(2);

βœ… 2. GET Request with Path Param (Single User)

@GET('api/users/{id}')
Future dynamic getSingleUser(@Path('id') String id);

// Usage:
final user = await apiServices.getSingleUser('2');

βœ… 3. POST Request (Create User)

@POST('api/users')
Future dynamic createUser(@Body() Map  String, dynamic body);

// Usage:
final response = await apiServices.createUser({
  'name': 'John Doe',
  'job': 'Developer',
});

βœ… 4. PUT Request (Full Update)

@PUT('api/users/{id}')
Future dynamic updateUser(@Path('id') String id, @Body() Map  String, dynamic body);

// Usage:
final response = await apiServices.updateUser('2', {
  'name': 'Jane Doe',
  'job': 'Manager',
});

βœ… 5. PATCH Request (Partial Update)

@PATCH('api/users/{id}')
Future dynamic patchUser(@Path('id') String id, @Body() Map  String, dynamic body);

// Usage:
final response = await apiServices.patchUser('2', {
  'job': 'Lead Developer',
});

βœ… 6. DELETE Request

@DELETE('api/users/{id}')
Future dynamic deleteUser(@Path('id') String id);

// Usage:
final response = await apiServices.deleteUser('2');

βœ… 7. GET with Multiple Query Parameters

@GET('api/users')
Future UserList getUserListWithQuery(@Queries() Map  String, dynamic queries);

// Usage:
final userList = await apiServices.getUserListWithQuery({
  'page': 2,
  'per_page': 5,
});

🎯 Summary

  • βœ… Retrofit makes HTTP API calls easier and cleaner in Flutter.
  • βœ… Dio handles network operations efficiently with options for logging, interceptors, and more.
  • βœ… You can handle GET, POST, PUT, PATCH, DELETE, and use Query/Path parameters using Retrofit decorators.

⭐ Happy Coding!