DioExtended

DioExtended is a thin wrapper over the dio HTTP client that simplifies networking in Flutter. It provides a clean, result-based API (ApiResult<T>) for handling requests and responses, reducing boilerplate and making your code more robust.

This package also includes ShakeForChucker, a developer helper that allows you to instantly open the Chucker network inspector just by shaking your device.

Table of Contents


Features

  • Simplified API: Handles requests and responses through a clean ApiResult<T> interface.
  • Automatic JSON Parsing: Easily decode responses to your model objects with a simple decoder function.
  • Built-in Token Refresh: Provides a callback mechanism to automatically handle authentication token expiration and retry requests.
  • Shake for Debugging: Integrate ShakeForChucker to open the network inspector with a simple gesture, perfect for development and QA.

Installation

Add dio_extended to your pubspec.yaml file. We'll use latest to always get the newest version.

dependencies:
  dio_extended: ^latest

Note:

  • The versions for chucker_flutter and shake are examples. Use the versions compatible with your project.

DioExtended: Simplified Networking

DioExtended is the core of this package. It streamlines HTTP requests and returns a consistent ApiResult<T> object for all calls, making error handling and data parsing straightforward.

Initialization

Set up your API client with a base URL and default headers.

import 'package:dio_extended/dio_extended.dart';

final api = DioExtended(
  baseUrl: 'https://api.example.com',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  },
);

// You can access the underlying Dio instance directly if needed
final dioInstance = api.dio;

If you want to create independent service, just do this on our class:

class CrudService extends DioExtended {
  CrudService() : super(baseUrl: 'YOUR-BASE-URL');
  /// Here you can use all function from DioExtend
  /// examples of its use are available ini Request Exampel 
}

GET Request Example

Making a GET request is simple. Provide a decoder function to parse the JSON response into your model object.

  /// Fetches a list of all posts from the API.
  ///
  /// Returns an [ApiResult] containing a list of [PostModel] objects on success,
  /// or an error message on failure.
  Future<ApiResult<List<PostModel>>> getPosts() async {
    return await callApiRequest<List<PostModel>>(
      request: () => get('/posts'),
      parseData: (data) => (data as List)
          .map((itemJson) => PostModel.fromJson(itemJson))
          .toList(),
    );
  }
	
  /// Example for single model
  Future<ApiResult<PostModel>> getPosts() async {
    return await callApiRequest<List<PostModel>>(
      request: () => get('/posts'),
      parseData: (data) => PostModel.fromJson(itemJson)
    );
  }

Using callApiRequest will make us easier to fetch and parsing with the result model. In controller side (business logic), you can checking the result just using isSuccess or not.

```
    final result = await _service.getPost();
    if (result.isSuccess) {
		   /// Your logic here
    }
```

Token Refresh (Optional)

To handle automatic token refresh, just overriding handleTokenExpired . The library will automatically use this callback when a request fails with a 401 status code (or you can set other code with tokenExpiredCode) and then retry the original request.

class CrudService extends DioExtended {
  CrudService() : super(baseUrl: 'https://jsonplaceholder.typicode.com', tokenExpiredCode:  401);

  /// Overriding [handleTokenExpired] to fetch new auth key or etc
  @override
  Future<dynamic> handleTokenExpired() async {
    final newHeader = await fetchNewAutn();

    /// Send callback as Map
    /// exemple {'Authentication': 'Bearer xxx'}
    return newHeader;
  }
 }

ShakeForChucker: Debug with a Shake

ShakeForChucker is a convenient utility for developers and QA testers. It integrates with the chucker_flutter package to open the network inspection UI when you shake the device.

Setup

Wrap your MaterialApp with the ShakeForChucker widget. Make sure to also add ChuckerFlutter.navigatorObserver to your app.

import 'package:flutter/material.dart';
import 'package:chucker_flutter/chucker_flutter.dart';
import 'package:dio_extended/src/chucker/shake_for_chucker.dart'; // Import path for ShakeForChucker

void main() {

  // Init chucker configs
  // Do this before runApp
  ShakeChuckerConfigs.initialize(
    showOnRelease: true,
    showNotification: true,
  );

  runApp(
    ShakeForChucker(
      // Number of shakes needed to trigger Chucker (default is 3)
      shakeCountTriggered: 3, 

      child: MaterialApp(
        title: 'DioExtended Demo',
        // This observer is required for Chucker to work correctly
        navigatorObservers: [
          ShakeChuckerConfigs.navigatorObserver,
        ],
        home: const MyHomePage(),
      ),
    ),
  );
}

Libraries

diox
A powerful Flutter library that enhances Dio with a simplified API response handler and adds a convenient 'shake-to-debug' feature to open Chucker.
models/api_result