op_rest_api_client 0.15.1
op_rest_api_client: ^0.15.1 copied to clipboard
A lightweight and flexible Dart HTTP client for RESTful APIs with structured error handling via op_result and support for identity-based authentication and token refresh.
Changelog #
[0.15.1] - 2025-07-22 #
- Added
dnsFailure
toOpRestApiErrorType
to distinguish DNS resolution issues from other network errors. - Upgrade http package to latest version (1.4.0)
[0.15.0] - 2025-07-14 #
Breaking changes #
OpRestApiIdentity.authorizationHeader()
now returnsString?
instead ofString
.- Return
null
to omit the header entirely.
- Return
OpRestApiErrorType.networkError
has been removed and replaced with three more specific error types:networkOffline
: device has no internet connection.networkUnreachable
: the device is connected but cannot reach the server (e.g., DNS failure, socket exception, timeout).gatewayError
: the server responded with a 502 or 504 gateway error.- Unified identity header handling: Removed
authorizationHeader()
fromOpRestApiIdentity
. Useheaders()
instead and includeAuthorization
as a regular entry if needed.
Enhancements #
- Improved error classification for more accurate handling and messaging of network-related failures.
0.14.1 - 2025-04-25 #
Enhancements #
- Fixed an issue in the README file.
- Updated
ExceptionHandler
to classifyClientException
as a network error. - Updated description in
pubspec.yaml
to mention support forop_result
and identity-based token handling. - Added
homepage
links inpubspec.yaml
. - Upgraded dependencies to latest stable versions.
0.14.0 - 2025-03-07 #
Added #
OpRestApiEndpoint
as a replacement for raw endpoint strings.endpointMap
now maps user-definedApiEndpointEnum
values toOpRestApiEndpoint
instead ofString
.
customValidator
as a replacement forerrorHttpStatusCodes
andsuccessHttpStatusCodes
,send()
as the new unified request method.
Breaking Changes #
- Removed
sendGet
,sendPost
,sendPut
,sendPatch
, andsendDelete
- The HTTP method is now determined directly from
OpRestApiEndpoint
.
- The HTTP method is now determined directly from
- Removed
successHttpStatusCodes
anderrorHttpStatusCodes
.- These were previously used to determine response success and failure based on predefined status codes.
- This functionality is now fully replaced by
customValidator
, which allows more flexible validation based on response body and status code.
- Removed
enumValues
andendpointMap
. - Renamed
ApiClientMethods
toOpRestApiClientMethods
- Renamed
ApiErrorType
toOpRestApiErrorType
- Renamed
Identity
toOpRestApiIdentity
- Renamed
restApiBodyEncoder
toopRestApiBodyEncoder
Migration Guide #
-
Update endpointMap to use OpRestApiEndpoint instead of String:
const Map<ApiEndpoints, OpRestApiEndpoint> apiEndpointMap = { ApiEndpoints.getUser: OpRestApiEndpoint('/user', OpRestApiClientMethods.get), ApiEndpoints.updateUser: OpRestApiEndpoint('/user/update', OpRestApiClientMethods.put), };
copied to clipboard -
Replace calls to
sendGet()
,sendPost()
, etc. withsend()
:// Before await apiClient.sendGet(endpoint: ApiEndpoints.getUser);
copied to clipboard// After await apiClient.send(endpoint: ApiEndpoints.getUser);
copied to clipboard -
If you previously used
successHttpStatusCodes
anderrorHttpStatusCodes
, migrate tocustomValidator
:// Before (Using `successHttpStatusCodes` & `errorHttpStatusCodes`) final result = await apiClient.send( endpoint: MyApiEndpoints.getUser, successHttpStatusCodes: [200, 202], // Considered successful errorHttpStatusCodes: {OpRestApiErrorType.notFound: [404]}, );
copied to clipboard// After (Using `customValidator`): OpResult<http.Response, MyCustomError>? myValidator(http.Response response) { if (response.statusCode == 200 || response.statusCode == 202) { return OpResult.success(response); } if (response.statusCode == 404) { return OpResult.failure(OpError(type: MyCustomError.notFound)); } return null; // Fallback to default handling } final result = await apiClient.send( endpoint: MyApiEndpoints.getUser, customValidator: myValidator, );
copied to clipboard
0.13.0 - 2025-03-03 #
Breaking Changes #
- Renamed package
json_api_client
toop_rest_api_client
-
Update all
import
statements:// No longer valid: import 'package:json_api_client/json_api_client.dart'; // Use this instead: import 'package:op_rest_api_client/op_rest_api_client.dart';
copied to clipboard -
Update
pubspec.yaml
dependencies:dependencies: op_rest_api_client: ^0.13.0
copied to clipboard
-
0.12.0 - 2025-03-03 #
Breaking Changes #
- Renamed
ApiOpResult
toOpResult
for consistency with the package naming convention. - Renamed
OpResultError
toOpError
to simplify error handling terminology. - Renamed
ApiOpResultErrorType
toApiErrorType
to better reflect its role as an API-specific error type.
These changes require updating all references to the renamed classes in your codebase.
[0.11.1] - 2025-02-27 #
Upgrades & Improvements #
- Upgraded to the latest
op_result
library: - Refactored codebase to align with
op_result
changes:- Updated all
failure()
calls to use the new factory constructor. - Ensured compliance with the new multiple error handling system.
- Updated all
[0.11.0] - 2025-02-24 #
New Features #
-
Added Support for
PUT
,PATCH
, andDELETE
Methods-
The API client now supports all major HTTP request methods, including:
sendPut()
sendPatch()
sendDelete()
-
These methods function similarly to
sendPost()
, allowing request bodies and encoded data. -
Usage Examples:
// PUT Request final response = await apiClient.sendPut( apiEndPoint: ApiEndpoints.updateUser, identity: userIdentity, body: {"name": "Updated Name", "email": "new@example.com"}, ); // PATCH Request final response = await apiClient.sendPatch( apiEndPoint: ApiEndpoints.partialUpdate, identity: userIdentity, body: {"status": "active"}, ); // DELETE Request final response = await apiClient.sendDelete( apiEndPoint: ApiEndpoints.deleteAccount, identity: userIdentity, );
copied to clipboard
-
-
Enhanced API Consistency
- The API client now follows a unified request structure for
POST
,PUT
,PATCH
, andDELETE
, ensuring consistent handling of request bodies. body
andencodedBody
work the same way across all methods.
- The API client now follows a unified request structure for
-
Updated Documentation & Macros
- The DartDoc macros now clarify that:
body
is optional forDELETE
requests.headers["authorization"]
cannot be used together withidentity
, but other headers can be combined.
- The DartDoc macros now clarify that:
[0.10.0] - 2025-02-22 #
Enhancements #
-
Added Support for
x-www-form-urlencoded
Request Body Encoding- The API client now supports sending requests using
application/x-www-form-urlencoded
. - If
encodedBody
is provided, it takes precedence overbody
, ensuring full control over pre-encoded data. - If
encodedBody
isnull
, the client automatically encodesbody
based on thecontent-type
header. - Encoding behavior:
"application/json"
(default) → Encoded as JSON."application/x-www-form-urlencoded"
→ Encoded as a query string.
- Example Usage:
final response = await apiClient.sendPost( apiEndPoint: ApiEndpoints.login, identity: null, body: {"email": "user@example.com", "password": "123456"}, ); // Defaults to JSON encoding
copied to clipboardfinal response = await apiClient.sendPost( apiEndPoint: ApiEndpoints.login, identity: null, headers: {"content-type": "application/x-www-form-urlencoded"}, body: {"email": "user@example.com", "password": "123456"}, ); // Automatically encodes as form-urlencoded
copied to clipboardfinal response = await apiClient.sendPost( apiEndPoint: ApiEndpoints.login, identity: null, encodedBody: "email=user%40example.com&password=123456", headers: {"content-type": "application/x-www-form-urlencoded"}, ); // Uses pre-encoded body
copied to clipboard
- The API client now supports sending requests using
-
New Public Helper:
restApiBodyEncoder
- The package now exports
restApiBodyEncoder
, a utility function to encode request bodies according to thecontent-type
. - Users can use this function if they need to manually encode a request body before passing it to
encodedBody
. - Example Usage:
import 'package:rest_api_client/rest_api_client.dart'; final String encoded = restApiBodyEncoder( {"email": "user@example.com", "password": "123456"}, "application/x-www-form-urlencoded", )!; print(encoded); // Output: email=user%40example.com&password=123456
copied to clipboard - This allows consistency between manual encoding and the library's automatic encoding logic.
- The package now exports
-
Updated
sendPost
Documentation- Clarified that
body
is encoded based on thecontent-type
header, defaulting toapplication/json
. - Explicitly documented that
encodedBody
takes precedence if provided. - Improved examples for JSON, form-urlencoded, and manually encoded bodies.
- Clarified that
[0.9.0] - 2025-02-14 #
Breaking Changes #
-
Renamed
rawToken
toidentityData
- This change makes the field name more representative of its purpose, indicating that it holds identity-related authentication data rather than just a raw token.
- Migration Guide:
- Update all instances of
rawToken
toidentityData
.
- Update all instances of
- Example:
final AuthIdentity identity = ...; print(identity.rawToken); // No longer valid print(identity.identityData); // Use this instead
copied to clipboard
-
Renamed
authToken()
toauthorizationHeader()
- This change clarifies that the method returns a properly formatted HTTP
Authorization
header instead of just a raw token. - Migration Guide:
- Replace calls to
authToken()
withauthorizationHeader()
.
- Replace calls to
- Example:
final Identity identity = ...; final String token = identity.authToken(); // ❌ No longer valid final String header = identity.authorizationHeader(); // ✅ Use this instead
copied to clipboard
- This change clarifies that the method returns a properly formatted HTTP
Enhancements #
- Improved naming conventions for better clarity and maintainability.
- Strengthened the API client's consistency in handling authentication.
Migration Notes #
- All implementations of
Identity<T>
must update their method signatures to reflect the new names. - If using
authToken()
in API request headers, replace it withauthorizationHeader()
. - If storing
rawToken
, update it toidentityData
.
[0.8.0] - 2025-02-13 #
Added #
-
Support for Token Refresh:
- The API client now supports automatic token refresh, ensuring persistent authentication without requiring the user to log in again when their access token expires.
- When an API request fails with 401 Unauthorized, the client will attempt a token refresh once before retrying the request.
- If the refresh is successful, the request is retried seamlessly using the new access token.
-
refresh
Method inIdentity
:- This new method is responsible for invoking the refresh token flow.
- It is automatically triggered when the access token is expired or when a 401 response is received from the API.
Fixes & Improvements #
- Optimized API request handling to automatically retry requests after a successful token refresh.
[0.7.0] - 2025-02-12 #
Breaking Changes #
- Removed
authHeaderKey
parameter- If needed, custom authorization headers can now be passed directly through the
headers
parameter in each API call. - As a result, when
identity
is specified in a request, theAuthorization
header now defaults to'Bearer $token'
.
- If needed, custom authorization headers can now be passed directly through the
Enhancements #
- Flexible Authentication Handling
- Both
headers
andidentity
can now be provided in a request. - However,
headers['Authorization']
andidentity
are mutually exclusive—ifheaders['Authorization']
is explicitly set,identity
will be ignored.
- Both
[0.6.0] - 2025-02-01 #
Added #
- Added support for custom headers in
OpRestApiClient
.- Users can now pass an optional
headers
parameter in API requests, allowing full control over authentication and custom headers. - If
headers
is provided,identity
is ignored, making the library independent of theIdentity
class and more flexible for various authentication methods. - This enables the use of API keys, session-based auth, and other custom headers without modifying the core API client.
- Users can now pass an optional
[0.5.0] - 2025-01-14 #
Added #
- Added support for an optional
onUnauthenticated
callback inOpRestApiClient
. This callback is triggered when a request returns anunauthenticated
error, enabling custom handling of unauthenticated states, such as logging out or displaying a user message. - The
onUnauthenticated
callback supports both synchronous and asynchronous functions, allowing flexibility for diverse use cases.
[0.4.0] - 2025-01-13 #
Added #
- Introduced
authToken()
inIdentity
, providing a method to retrieve the authentication token regardless of the typeT
of theIdentity
. This enhances flexibility and ensures a consistent way to access tokens in various implementations. - Renamed
token
inIdentity
torawToken
to better distinguish it from theauthToken()
method, which provides a processed or extracted authentication token.
[0.3.0] - 2025-01-13 #
Added #
- Made
Identity
a generic class, enabling the usage of tokens with types other thanString
. This increases flexibility and allows for better type safety in applications that use custom token types.