chopper
chopper copied to clipboard
Will support Rxdart?
I am Android developer. It is glad to see this project. Will it support Rx pattern? Also, capture common errors like network unavailable, status code not 200 and throw exception.
If supported Rx pattern, assume to like it || V
import "dart:async";
import 'package:chopper/chopper.dart';
part "my_service.chopper.dart";
@ChopperApi(baseUrl: "/resources")
abstract class MyService extends ChopperService {
static MyService create([ChopperClient client]) => _$MyService(client);
@Get(url: "{id}")
Observable<Response> getResource(@Path() String id);
@Get(headers: const {"foo": "bar"})
Observable<Response<Map>> getMapResource(@Query() String id);
@Post(url: 'multi')
@multipart
Observable<Response> postResources(
@Part('1') Map a,
@Part('2') Map b,
@Part('3') String c,
);
@Post(url: 'file')
@multipart
Observable<Response> postFile(
@FileField('file') List<int> bytes,
);
}
In RxDart, a Future<T> can be treated as a Single<T> so this more or less already supports RxDart. It makes more sense to model API calls as Single<T> anyways, since there's going to be one response per request.
From what I remember with Rx Pattern and retrofit, the request is not trigger until you start listening the Observable, which is not really common in Dart and I personally don't see the advantage of it (maybe I am wrong)
But if you just want to use Observable methods you can use Observable.fromFuture
final stream = Observable.fromFuture(service.getResource('id'))
the request is not trigger until you start listening the Observable, which is not really common in Dart
As far as I know, this is how Futures behave as well. No work is done with a Future until you await
or .then
it.
the request is not trigger until you start listening the Observable, which is not really common in Dart
As far as I know, this is how Futures behave as well. No work is done with a Future until you
await
or.then
it.
not sure about this.
main() async {
test();
await Future.delayed(Duration(seconds: 5));
print('world ${new DateTime.now()}');
}
Future test() async {
print('hello ${new DateTime.now()}');
}
test function is executed even if not await
of then
Another point where adding native rxdart support would be great is the need to map response everytime to a specific body:
Observable<List<Plant>> fetch() => Observable.fromFuture(
api.getPlants(),
).map((result) => result.body);
It's a little annoying :P
And because it's better to throw any Exception
using reactive streams I add:
- custom
errorConverter: HttpExceptionErrorConverter()
class HttpExceptionErrorConverter extends ErrorConverter {
@override
Response convertError<ErrorType, T>(Response response) {
final base = response.base;
final message = "${base.statusCode} ${response.body}";
return response.replace<dynamic>(
bodyError: HttpException(message, uri: base.request.url),
);
}
}
- and custom
interceptors: <dynamic>[ThrowExceptionInterceptor()]
class ThrowExceptionInterceptor implements ResponseInterceptor {
@override
Response onResponse(Response response) =>
response.error is Exception || response.error is Error
? throw response.error
: response;
}
this is calladapter in retrofit. I really hope this can be support.
We should definitely do this.
However, right now I'm working on the docs so Chopper can be as user-friendly and documented as possible. There are some roadblocks related to library maintenance along the way which should be cleared (like nullability support), but support for Rx types should be discussed and implemented in the near future. No promises though, maybe this year. 😅
But we have a support, as I see. :) This is a little addition, to use the map call. Or to use Singles. :)