h)

Version License Contributions welcome GitHub Sponsors

Contents

πŸ”½ Click to expand

Features

  • πŸ”„ Automatic token refresh with queue-safe retry
  • βš™οΈ onBeforeRefreshRequest to mutate refresh payload
  • πŸ›  Parsing responses into models or lists using INetKitModel
  • πŸ§ͺ Configurable base URLs for development and production
  • 🌐 Internationalization support for error messages

Sponsors

A big thanks to our awesome sponsors for keeping this project going!️ Want to help out? Consider becoming a sponsor!

Jurnalle

Getting started

Initialize

Initialize the NetKitManager with the parameters:

import 'package:net_kit/net_kit.dart';

final netKitManager = NetKitManager(
  baseUrl: 'https://api.<URL>.com',
  devBaseUrl: 'https://dev.<URL>.com',
  // ... other parameters
);

Extend the model

Requests such as: requestModel andrequestList require the model to extend INetKitModel in order to be used with the NetKitManager. By extending, INetKitModel fromJson and toJson methods will be needed to be implemented, so the model can be serialized and deserialized.

class TodoModel extends INetKitModel {}

Sending requests

Request a Single Model

Future<RandomUserModel> getRandomUser() async {
  try {
    final result = await netKitManager.requestModel<RandomUserModel>(
      path: '/api',
      method: RequestMethod.get,
      model: const RandomUserModel(),
    );
    return result;
  }

  /// Catch the ApiException and handle it
  on ApiException catch (e) {
    /// Handle the error: example is to throw the error
    throw Exception(e.message);
  }
}

Request a List of Models

Future<List<ProductModel>> getProducts() async {
  try {
    final result = await netKitManager.requestList<ProductModel>(
      path: '/products',
      method: RequestMethod.get,
      model: const ProductModel(),
    );
    return result;
  }

  /// Catch the ApiException and handle it
  on ApiException catch (e) {
    /// Handle the error: example is to throw the error
    throw Exception(e.message);
  }
}

Send a void Request

Future<void> deleteProduct() async {
  try {
    await netKitManager.requestVoid(
      path: '/products',
      method: RequestMethod.delete,
    );
    return;
  }

  /// Catch the ApiException and handle it
  on ApiException catch (e) {
    /// Handle the error: example is to throw the error
    throw Exception(e.message);
  }
}

Setting Tokens

The NetKitManager allows you to set and manage access and refresh tokens, which are essential for authenticated API requests. Below are the methods provided to set, update, and remove tokens.

Setting Access and Refresh Tokens

To set the access and refresh tokens, use the setAccessToken and setRefreshToken methods. The accessToken token will be added to the headers of every request made by the NetKitManager. Note: these should be set on every app launch or when the user logs in.

/// Your method to set the tokens
void setTokens(String accessToken, String refreshToken) {
  netKitManager.setAccessToken(accessToken);
  netKitManager.setRefreshToken(refreshToken);
}

User Logout

When a user logs out, you should remove the access and refresh tokens using the removeAccessToken and removeRefreshToken methods.

Example:

/// Method to log out the user
void logoutUser() {
  netKitManager.removeAccessToken();
  netKitManager.removeRefreshToken();
}

Refresh Token

NetKitManager provides a robust and RFC-compliant refresh token mechanism to ensure seamless and uninterrupted API communication, even when access tokens expire.

  1. When a request fails with a 401 Unauthorized, NetKit will automatically:
  2. Pause the failing request and any subsequent requests.
  3. Attempt to refresh the access token via the configured refreshTokenPath.
  4. Retry the failed requests using the new token upon successful refresh.

Refresh Token Initialization

To use the refresh token feature, you need to initialize the NetKitManager with the following parameters:

Parameter Required Description
refreshTokenPath βœ… Endpoint to request a new access token using the refresh token.
onTokenRefreshed βœ… Callback triggered after tokens are successfully refreshed.
refreshTokenBodyKey βž– Key for the refresh token in the refresh body (default: "refreshToken").
accessTokenBodyKey βž– Key for the access token in the refresh body (default: "accessToken").
removeAccessTokenBeforeRefresh βž– Whether to strip access token header during token refresh (default: true).
accessTokenPrefix βž– Prefix added to accessToken in headers (default: "Bearer").
onBeforeRefreshRequest βž– Allows modifying headers/body before refresh is sent.

Refresh Token Example


final netKitManager = NetKitManager(
  baseUrl: 'https://api.<URL>.com',
  devBaseUrl: 'https://dev.<URL>.com',
  refreshTokenPath: '/auth/refresh-token',

  /// Called after a successful refresh
  onTokenRefreshed: (authToken) async {
    await secureStorage.saveTokens(
      accessToken: authToken.accessToken,
      refreshToken: authToken.refreshToken,
    );
  },

  /// Optional: remove the Authorization header before making refresh request
  removeAccessTokenBeforeRefresh: true,

  /// Optional: override the default prefix "Bearer"
  accessTokenPrefix: 'Token',

  /// Optional: customize refresh request before it is sent
  onBeforeRefreshRequest: (options) {
    options.headers['Custom-Header'] = 'MyValue';
    options.body['client_id'] = 'your_client_id';
    options.body['client_secret'] = 'your_secret';
  },
);

How refresh token works

The refresh token mechanism in NetKitManager ensures that your access tokens are automatically refreshed when they expire, allowing for seamless and uninterrupted API requests. Here’s how it works:

πŸ” Token Expiry Detection:

  • When an API request fails with a 401 Unauthorized status code, NetKitManager automatically detects that the access token has likely expired.

πŸ”„ Token Refresh Request:

  • It then sends a request to the configured refreshTokenPath endpoint to obtain new access and refresh tokens.
  • The request body includes the current refresh token, and optionally other custom fields.

βœ… Updating Tokens:

  • Once new tokens are received:
    • The Authorization header (or other configured header) is updated with the new access token.
    • The onTokenRefreshed callback is triggered so you can store the new tokens securely.

πŸ” Retrying the Original Request:

  • The original request that failed is automatically retried with the new access token.
  • Any other requests that were waiting during token refresh are also retried in order.

This process ensures that your application can continue to make authenticated requests without requiring user intervention when tokens expire.

Logger Integration

The NetKitManager uses a logger internally, for example, during the refresh token stages. To add custom logging, you need to create a class that implements the INetKitLogger interface. Below is an example of how to create a NetworkLogger class:

You can find the full example of NetworkLogger here.


final netKitManager = NetKitManager(
  baseUrl: 'https://api.<URL>.com',
  logger: NetworkLogger(),
  // ... other parameters
);

Migration Guidance

➑️ For detailed upgrade steps and breaking changes, see the full Migration Guide.

Planned Enhancements

Feature Status
Internationalization support for error messages βœ…
No internet connection handling βœ…
Provide basic example βœ…
Provide more examples and use cases in the documentation βœ…
MultiPartFile upload support βœ…
Refresh Token implementation βœ…
Enhance logging capabilities with customizable log levels βœ…
Implement retry logic for failed requests 🟑
Add more tests to ensure the package is robust and reliable βœ…
Authentication Feature βœ…
Add Clean Architecture example 🟑

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

License

This project is licensed under the MIT License.

Libraries

net_kit