retrofit
retrofit copied to clipboard
Retrofit 3.x Things
Currently no plans for a Retrofit 3.x. Just tracking changes in a single issue instead of many.
- Mock behavior should invoke the implementation method for each
Call.execute()
/Call.enqueue()
. Currently it only invokes it once and reuses the result for every clonedCall
. - Eliminate
Retrofit
-wide knowledge of callback executor. This should be at best a first-partyCallAdapter.Factory
which you can apply (if you want) and which can target all calls or just those annotated with something like@MainThread
.
Will there be a simple way in order to retry a call n times? This would come very handy when there is a call that should be retried after an error. I was hoping for something like: request.retry(5);
To do this with Observables we use a custom transformer that gets tacked onto request invocations that takes in the number of retries.
Curious if for a 3.x it would be appropriate to have HttpException
be a part of the retrofit
module, instead of creating it separately in each adapter that is created. Is there a reason for this currently?
There's no use for it in the main module at present which is why each adapter defines its own. This change wouldn't need to wait for 3.x as it can be added in a backwards compatible-way.
On Fri, Feb 10, 2017, 6:24 PM John [email protected] wrote:
Curious if for a 3.x it would be appropriate to have HttpException be a part of the retrofit module, instead of creating it separately in each adapter that is created. Is there a reason for this currently?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/2180#issuecomment-279093946, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEbkNipR8MdHziHDxfyQPhnG58fbAks5rbPG8gaJpZM4LxEk6 .
Gotcha. So do you think that each should continue to have its own copy? The benefits I could see with unifying mostly come from just reducing the duplication. Is this something you would be interested in seeing in a PR, or do you prefer keeping them separate?
I'd be okay with a PR. Basically copy paste it into the main module and then change all the existing ones to extend. I'm not happy it has to be non-final in the main module, but it's only an exception so not a big deal.
On Fri, Feb 10, 2017, 6:48 PM John [email protected] wrote:
Gotcha. So do you think that each should continue to have its own copy? The benefits I could see with unifying mostly come from just reducing the duplication. Is this something you would be interested in seeing in a PR, or do you prefer keeping them separate?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/2180#issuecomment-279097602, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEd7JMYB1r3-DiOeglVnbi7LAApT5ks5rbPdmgaJpZM4LxEk6 .
I created #2194 to track that. Feel free to send a PR over the weekend. Otherwise I'll grab it on Monday. I need to release really soon but I'll wait for this.
@TobiasReich no plans for retry. You can already call clone()
on a Call
to retry and so implementing that at the application level seems more appropriate. You can write a CallAdapter
to return a custom type that provides a nice API for retry. Because of the behavior in sync vs. async mode and what executor the delay happens on being unclear I don't think I want it in the library.
You can add code below to your okhttp interceptor to archieve retry mechanism.
new OkHttpClient.Builder()
.addInterceptor(new RetryInterceptor(3)) // must add at first
// ...
.build();
The RetryInterceptor is
public class RetryInterceptor implements Interceptor {
private final int mRetryTimes;
public RetryInterceptor(int retryTimes) {
mRetryTimes = retryTimes;
}
@Override
public Response intercept(Chain chain) throws IOException {
int retryTimesLeft = mRetryTimes;
for (; retryTimesLeft > 0; --retryTimesLeft) {
try {
return chain.proceed(chain.request());
} catch (IOException ignore) {
}
}
throw new IOException("still fail after retry " + mRetryTimes + " times");
}
}
The code is not tested yet. But I think it's quite simple to understand.
Kotlin Will retrofit support async/await in future?
~It already does https://github.com/gildor/kotlin-coroutines-retrofit~
Built-in now
On Sun, Mar 26, 2017, 5:03 AM Skullper [email protected] wrote:
Kotlin Will retrofit support async/await in future?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/2180#issuecomment-289267555, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEXo8FGgr0JKhEFIJbBbn1L7ZS4HFks5rpinTgaJpZM4LxEk6 .
Return easy error api from Retrofit1.
@JakeWharton Can we remove HttpException
in 3.x? Since it has been unified across the modules here: https://github.com/square/retrofit/commit/4546d5d88a331db779e72fbf453bc5abd69edd2d.
Everything deprecated gets removed in major version bumps.
On Mon, Aug 28, 2017 at 11:41 AM Jared Burrows [email protected] wrote:
@JakeWharton https://github.com/jakewharton Can we remove HttpException in 3.x? Since it has been unified across the modules here: 4546d5d https://github.com/square/retrofit/commit/4546d5d88a331db779e72fbf453bc5abd69edd2d .
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/2180#issuecomment-325390373, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEVOG3Mw1AuQvlTPjsxh591r7LlgIks5sct-TgaJpZM4LxEk6 .
@JakeWharton Great.
Thanks. That's what I was asked for.
It wasn't what you were asking for. The error handling of 1.x was terribly designed (by me) and will not be returning.
On Mon, Aug 28, 2017 at 12:20 PM Vasyl Khrystyuk [email protected] wrote:
Thanks. That's what I was asked for.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/2180#issuecomment-325401394, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEUz50bLGSZclpRkDek-gy7xDnS9Qks5scujlgaJpZM4LxEk6 .
Most of people get http error with adequate, well-formatted message. Yep, not all. But still, most cases the response can be converted well with built-in or custom converters, like those for 2xx responces. And this works perfect in version1. People need this. On stackoverflow I saw workarounds like creating new retrofit instance(or getting instance as singletons) just for accessing converters. Or others solutions(http://bytes.babbel.com/en/articles/2016-03-16-retrofit2-rxjava-error-handling.html)
Your assumptions are incorrect. The samples show how to correctly handle the case where you want to deserialize error responses using a converter.
On Mon, Aug 28, 2017 at 1:02 PM Vasyl Khrystyuk [email protected] wrote:
Most of people get http error with adequate, well-formatted message. Yep, not all. But still, most cases the response can be converted well with built-in or custom converters, like those for 2xx responces. And this works perfect in version1. People need this. On stackowerflow I saw workarounds like creating new retrofit instance(or getting instance as singletons) just for accessing converters. Or others solutions( http://bytes.babbel.com/en/articles/2016-03-16-retrofit2-rxjava-error-handling.html )
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/2180#issuecomment-325412378, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEaxFtJ7xQPXYfPQicQIs8P5xqonjks5scvKJgaJpZM4LxEk6 .
@msangel Here is the sample: https://github.com/square/retrofit/blob/master/samples/src/main/java/com/example/retrofit/ErrorHandlingAdapter.java.
That one doesn't really cover it. I guess there isn't a sample for it. It's a combination of https://github.com/square/retrofit/blob/e6a7cd01657670807bed24f6f4ed56eb59c9c9ab/samples/src/main/java/com/example/retrofit/DeserializeErrorBody.java and https://speakerdeck.com/jakewharton/making-retrofit-work-for-you-droidcon-uk-2016?slide=214
Yep. The first sample is good. It is worst then retrofit1 solution just in that moment that error know nothing about it's context. Adding to the error (transient) link to the retrofit instance it was created with will solve the gap. And maybe adding method like getErrorBodyAs(SomeType.class)
to the HttpError will fulfill it completely.
That is not possible because of serialization requirements.
On Mon, Aug 28, 2017, 11:40 PM Vasyl Khrystyuk [email protected] wrote:
Yep. The first sample is good. It is worst then retrofit1 solution just in that moment that error know nothing about it's context. Adding to the error (transient) link to the retrofit instance it was created with will solve the gap. And maybe adding method like getErrorBodyAs(SomeType.class) to the HttpError will fulfill it completely.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/2180#issuecomment-325546147, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEbrvCznhcf7fVD9Yk9YCJGRdPZfxks5sc4gxgaJpZM4LxEk6 .
Any plan to support custom annotation on an interface in 3.x?
I don't know what that means
On Thu, Sep 7, 2017 at 5:26 AM vidhithakrar [email protected] wrote:
Any plan to support custom annotation on an interface in 3.x?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/2180#issuecomment-327745074, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEZwme3tpMmZcMDerpUUaaLRSlBsrks5sf7bTgaJpZM4LxEk6 .
Perhaps something like:
@BaseUrl("https://host1.mydomain.com")
public interface MyService1 {
@GET("get_something")
Call<Something> getSomething();
// ... Many other methods that use the same baseUrl
}
Where @BaseUrl
is a user-defined annotation. Then CallAdapter.Factory should receive not just method annotations but also the annotations declared on the interface.
I can imagine why this could be useful. Instead of creating a customized Retrofit client before calling retrofit.create(X.class)
one could create a custom CallAdapter.Factory that would parse those annotations and provide an accordingly customized Retrofit instance to a CallAdapter.
@zergtmn Yes, something like that. One more thing to add is we get Method level annotation in the CallAdapterFactory but not the Method Parameter level.
public interface FooServices {
@GET("/path")
@MethodCustom
Call<Foo> foo(@Custom String custom);
}
In the CallAdapterFactory, We get @MethodCustom annotation but not the @Custom.
I see no use to doing that. What would you use it for?
On Thu, Sep 7, 2017 at 1:38 PM vidhithakrar [email protected] wrote:
@zergtmn https://github.com/zergtmn Yeah, something like that. One more thing to add is we get Method level annotation in the CallAdapterFactory but not the Method Parameter level.
public interface FooServices { @get https://github.com/get("/path") Call foo(@Custom https://github.com/custom String custom); }
We do not get
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/2180#issuecomment-327862504, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEVczlTigK-cNrHpzIZkScuDF3VDUks5sgCIlgaJpZM4LxEk6 .
One major point on my whish-list for Retrofit 3 is better type converters.
Moshi does this excellently and Google's Room is by far the most intuitive solution.
I know that Retrofit is a bit different in that it features different adapters for the request body and for strings, but it feels like the converter API needs some improvement.
Think of use cases where you want to have one type converter convert from ResponseBody
to Foo
and another that can then convert from Foo
to Bar
. That way you could e.g. parse.
I've personally worked on a conversion API some time ago and would be happy to help in the development of Retrofit 3.
Custom annotation example: interface with the filename as a parameter. We are registering a custom handler for methods with such annotations. Then when the method gets called - the execution will be delivered to the handler. So I will read the file, will process it(compress in my case) and will send in the custom manner.
And I do not need to write any custom wrapper around the interface just for inject some specific functionality to the generated class.
Another case: special custom AUTH, when the credentials are just additional request parameters(quite popular case), so we will write a custom handler that will set the credentials. So setting custom annotation and writing handler for it will solve the problem.
Another case: we can write one custom annotation for queries to one host, and the second - for queries to the second host.
I believe this annotation should be able to change not only request but the response as well. Actually, you have already builtin logic for convert the response via converters, its good, but still few things there are missing (current retrofit
object);