sturdy_http 0.5.0
sturdy_http: ^0.5.0 copied to clipboard
A strongly typed, event-based, reliable HTTP client that wraps `Dio`.
SturdyHttp #
A strongly typed, event-based, reliable HTTP client that wraps Dio.
Features #
SturdyHttp is a very opinionated HTTP client that offers an idiomatic API for interacting with a Dio instance. This includes:
- Executing requests that are actual objects themselves (see
NetworkRequest) - Event-based notifications of things you want to know about during request execution (see
SturdyHttpEventListener) - Worker
Isolatedeserialization to avoid bogging down the mainIsolate(seeDeserializer) - Clear enumeration of response types (see
NetworkResponse)
Note At Betterment, we've used
SturdyHttpinternally for the past year. It's been battle-tested across over 200 network request call sites throughout the application and its opinionated nature is a direct result of this experimentation. We're always open to making it more flexible if it makes sense to do so; feel free to drop an Issue to discuss doing so!
Usage #
Start by creating your SturdyHttp instance, likely during application bootstrap:
return SturdyHttp(
baseUrl: '$baseUrl/api/',
eventListener: eventListener,
interceptors: interceptors,
);
Then, execute requests:
Future<Result<MyData>> fetch({required int id}) async {
return _client.execute<Json, MyData>(
GetRequest('/v6/data/${id}'),
onResponse: (r) => r.maybeWhen(
ok: (json) => Result.success(MyData.fromJson),
orElse: () => Result.failure(r),
),
);
}
Note Because
Resulttypes are very opinionated,SturdyHttpdoes not return aResultbut rather the generic type provided toexecute(and returned byonResponse). If this type fails to be deserialized, anExceptionwill be thrown. This can be managed by adding an extension on top of the client itself, which is how we interact with the client ourselves. For example:
extension SturdyHttpX on SturdyHttp {
/// Invokes [execute] on the [SturdyHttp] and conforms its result to a [Result]
/// based on the provided [onResponse].
///
/// In the event that an [Exception] is thrown by [execute], the returned
/// [Result]s right-side will contain a [NetworkError] describing the [Exception]
Future<Result<M, NetworkError>> executeForResult<R, M extends Object>(
NetworkRequest request, {
required Result<M, NetworkError> Function(NetworkResponse<R> response) onResponse,
}) async {
return Result.fromAsync(
() => execute(
request,
onResponse: onResponse,
),
).match(ok: (o) => o, error: (e) => Result.error(NetworkError.forException(e)));
}
}
Warning We're considering open-sourcing our
Resulttype and integrating it intoSturdyHttp. If we did, we'd likely changeexecute's return type to be aResult, and offerexecuteUnsafeas the non-Result(i.eExceptionthrowing) alternative. This would be a breaking change.
Contributing #
If you run into a bug or limitation when using SturdyHttp, we'd love your help in resolving it. First, it would be awesome if you could open an issue to discuss. If we feel like we should move forward with a change and you're willing to contribute, create a fork of SturdyHttp and open a PR against the main repo.