square / retrofit

A type-safe HTTP client for Android and the JVM
https://square.github.io/retrofit/
Apache License 2.0
42.81k stars 7.28k forks source link

Multiplatform support #3181

Open romtsn opened 4 years ago

romtsn commented 4 years ago

Given that okio went multiplatform already, and okhttp is slowly going towards that direction, would it be possible for Retrofit to go multiplatform some day? I'm just curious what are the required steps for this, apart from the actual conversion to Kotlin (which is not planned yet, according to the issue I mentioned).

I would see moving from reflection-based annotation parsing (as I assume it's not working in native) to compile-time annotation processing + codegen of interfaces' implementations (instead of create method) as a necessary step, but what could be else?

JakeWharton commented 4 years ago

No earlier than 2 years. More realistically probably 4 or 5 years.

To say Okio went multiplatform is true, but it lacks the facilities for even implementing OkHttp in multiplatform contexts (specifically, timeouts and deadlines). So we're really blocked on Okio finishing itself going multiplatform and exposing this behavior, likely through coroutines. Additionally, blocking IO simply doesn't work in places like JavaScript so it's not clear Okio is even ready to be utilized there. Essential functionality like the gzip and deflate support are absent on non-JVM platforms. That's the first blocker.

Next, OkHttp is now written in Kotlin but it's API is coupled to the JVM. Decoupling this will be a large effort and almost certainly require breaking the API. Not to mention the reimplementation on JS and native, or delegation to platform-specific equivalents in a way that provide consistent behavior. This can probably be done on native, but OkHttp doesn't seem the right layer of abstraction for adapting JS clients. That's the second blocker.

Finally, Retrofit relies on mechanisms which are not available on JS or native or do not have satisfying equivalents. Switching to code generation is not at all easy because of the behavior of converter factories and call adapter factories. This was evaluated 5-ish years ago and deemed infeasible or requiring too many trade-offs. That leaves reflection, which is possible, but blocked on Kotlin again. And it would also would likely mean taking a kotlin-reflect dependency on the JVM which is currently a complete non-starter.

Now Retrofit is a layer where abstraction over multiple HTTP clients could be done, and it probably could be done in about a year. But it would mean severely restricting the API where there weren't any converters or adapters so suspend fun was your only choice and kotlinx.serialization types, UByteArray, or String were the only supported return types (or Response<T> of those types). That might be something I would build, but it would be the opposite of Retrofit.

It's not that I'm opposed to this. I want this. It just doesn't seem feasible in the next few years as it requires significant work on our upstream dependencies first. I'll be pushing for, following, and in some cases contributing that work. But this is definitely not something you should be holding your breath on.

yangwuan55 commented 4 years ago

Excluding js, is it easier to implement on other platforms?Android,IOS,MacOS,Windows,Linux and so on.

JakeWharton commented 4 years ago

No

On Sun, Sep 1, 2019, 1:55 AM mengrong.yang notifications@github.com wrote:

Excluding js, is it easier to implement on other platforms?Android,IOS,MacOS,Windows,Linux and so on.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/3181?email_source=notifications&email_token=AAAQIENG2P7XHYEGMV6PBTDQHNKOJA5CNFSM4IH26TZ2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD5T3FTI#issuecomment-526889677, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAQIEM52EK3STXOINFJMLLQHNKOJANCNFSM4IH26TZQ .

CharlieTap commented 3 years ago

Is this any more possible now then when this was posted a year ago?

At a glance OkHttp and Okio seem to be in the similar positions so I would guess not, but would be interesting to hear if there's any internal conversations amongst yourselves

JakeWharton commented 3 years ago

No change.

Maybe with KSP eventually supporting multiplatform, but it's not super interesting to me right now to explore considering how experimental it is.

On Thu, Oct 15, 2020, at 1:52 PM, CharlieTap wrote:

Is this any more possible now then when this was posted a year ago?

At a glance OkHttp and Okio seem to be in the similar positions so I would guess not, but would be interesting to hear if there's any internal conversations amongst yourselves

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/square/retrofit/issues/3181#issuecomment-709490506, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAQIEOLUVANILFTEH33Z6DSK4ZF3ANCNFSM4IH26TZQ.

ursusursus commented 2 years ago

@JakeWharton ksp is stable now

yschimke commented 2 years ago

Is the status the same here? Would OkHttp 5.0 change the equation at all? https://github.com/square/okhttp/issues/6963

JakeWharton commented 2 years ago

I don't think it changes all that much until there's a working client on multiple platforms that I can evaluate. And I'm concerned about mentions of not supporting JS such that I may have to remove OkHttp entirely from Retrofit's public API to accomplish multiplatform.

xiazunyang commented 2 years ago

Without relying on OkHttp, Ktor client seems like a good candidate

JakeWharton commented 2 years ago

Possibly, although it itself is merely a wrapper around actual HTTP clients like OkHttp. I would prefer OkHttp for obvious reasons, but I also want to make sure it's the right reasons. Currently we gain a lot from exposing it as public API and I'm not sure Ktor client has the same level of features because it's an abstraction over existing clients.

For example, OkHttp's tagging allows us to expose details about the Retrofit method to OkHttp interceptors. This is a wildly powerful feature that is going to be very challenging to replicate in a multiplatform context both because of the problem of the multiplatform HTTP client but also the lack of reflection in multiplatform.

JakeWharton commented 2 years ago

Weirdly have used the Ktor client API in two projects since writing that comment and it is very, very painful. Maybe they fixed it up in 2.0, but the latest stable one is not pleasant and I would not want to build on top of it here.

yschimke commented 2 years ago

If it makes retrofit happen, we should work out how to try to make OkHttp JS happen.

JakeWharton commented 2 years ago

JS is my most used platform after JVM/Android. I almost never use native. If you don't make it happen I'll just ship an HTTP client abstraction similar to Retrofit 1 with end-to-end coroutines and it will be a little painful but work just fine. It's probably a wise design decision anyway because I also would love to support Java 11's built-in HTTP client, too. This makes multiplatform HTTP client configuration a separate concern from Retrofit's perspective. So if OkHttp chooses to not work on JS then you can only do common configuration on JVM/Android/native and that's fine from Retrofit's perspective. In this regard I like Ktor client's design.

plusmobileapps commented 2 years ago

I did just recently come across a library that is multiplatform and inspired by Retrofit, called Ktorfit. Not sure if something similar could be done with respect to Retrofit, although that implementation is built on top of Ktor 2.0 and used KSP.

rockyoung commented 2 years ago

For most people, the core of retrofit, which is the most popular feature, is that it makes the network layer implementation of the application declarative (describe the API by interface with methods and the help of annotations, that is really cool), although this is implemented through reflect.Proxy (and this is now possible achived by ksp or kapt), while adapter and converter are specific to the extensibility and flexibility on the jvm platform, and yes, they are currently part of retrofit too , but they are not the most important part, and discarding them temporarily will not "be the opposite of Retrofit", if there are more options for adapter and converter at multiplatform in the future, it will not be too late to add these features back.

so I think it's time to move on.

ankushg commented 1 year ago

Excited to see that Retrofit 5.0.0-alpha4 added experimental JS and iOS support!

That obviously doesn't address any of the reflection-based reasons that Retrofit isn't multiplatform-friendly, but I figured that this was relevant info for folks following or stumbling across this issue

ZacSweers commented 1 year ago

That's OkHttp, not Retrofit

luludevmuniz commented 4 months ago

5 years after, what's the current thoughts about this one?

yangwuan55 commented 4 months ago

5 years after, what's the current thoughts about this one?

We can use ktorfit

cj-marius-duna commented 2 weeks ago

@JakeWharton No rush from our side, we just want to know whats the current status for multiplatform?

JakeWharton commented 2 weeks ago

Nonexistent

artemyto commented 2 weeks ago

No rush from our side, we just want to know whats the current status for multiplatform?

OkHttp has dropped multiplatform support in 5.0.0-alpha.13. Given that information you can estimate chances for Retforit to get multiplatform support.

JakeWharton commented 1 week ago

Sort of. OkHttp started by trying to make its existing API multiplatform, and that wasn't going well. It is what was removed.

Instead, the plan is to build a dedicated HTTP model in isolation that can be used by libraries like Coil or Retrofit. OkHttp will be one implementation of that model, but you could also use another.