Apollo-android: Add KotlinNative support

Created on 24 Jul 2019  路  16Comments  路  Source: apollographql/apollo-android

After introducing support for Kotlin model generation there is nothing stopping us from adding Kotlin Native support and make it as multi platform library. This feature can be broken into 2 phases:

Phase 1:

  • [x] Introduce pure Kotlin version of apollo-api module, avoid any JVM references
  • [x] Introduce light weight implementation of apollo-runtime with ResponseReader / ResponseWriter / InputFieldWriter support
  • [x] Investigate any changes required by Gradle Plugin
  • [x] Investigate multi platform artifacts publishing
  • [x] Provide sample App

After this phase Apollo enables basic support for multi platform projects and provides these functionalities:

  • generate Kotlin models
  • serialize / deserialize models to / from raw JSON (we can utilize multi platform library such as Kotlinx Serialization for JSON support)
  • support generating cache keys for normalized cache implementation

Phase 2 might include adding support for multi platform network client, http / normalized cache.

Feature

Most helpful comment

@sav007 let me know if you need any help testing K/N support from iOS, I would be VERY happy to help 馃榿

All 16 comments

@sav007 let me know if you need any help testing K/N support from iOS, I would be VERY happy to help 馃榿

First step could be to actually migrate to Kotlin from Java source code

Is anyone working on it? I would like to start working on it with Phase 0 being moving code from Java to Kotlin and then carrying on to Phase 1 and Phase 2.

@Sarthak30 sure you can take a look at:

Introduce pure Kotlin version of apollo-api module, avoid any JVM references

So basically we should take existing api module create new version apollo-api-kotlin.

So can you create a repo for this, where I can maybe start committing code and maintain a project there? How do you normally go around this? Or should I create a repo in my profile and maybe you can fork it some time?

@Sarthak30 we do Pull Requests.

There's one that has just been opened for moving the apollo-api module to kotlin => https://github.com/apollographql/apollo-android/pull/1504

Although I realize it converts in-place. That could be risky. @tasomaniac shouldn't we setup some japicmp before the migration to ensure everything behaves the same ? Like in okhttp did when they switched to kotlin

@martinbonnin definitely makes sense. I was gonna propose that we can create a kotlin-migration branch and merge this one there and then setup tools to verify that it is backward compatible.

One good and simple practice is to keep tests in Java and use them to make sure that it works as before when calling from Java.

@martinbonnin @tasomaniac
I'm afraid if we touch existing apollo-api module we won't avoid the dependency to Kotlin stdlib. Means we will bring this Kotlin library into Java world, looking into history with OkHttp Java folks won't be happy at all.

Plus I would love to remove some classes out from the apollo-api like:
/cache/http/*.java, /internal/*.java etc. Leave only those that absolutely required by generated Kotlin models.

Do you think it make sense to create a new module apollo-api-kotlin?

I am in favor of having a new module.

@sav007 do you mean we shouldn't pull the Kotlin stdlib for java users ? Does it mean we'll have to maintain two different artifacts, apollo-api and apollo-api-kotlin ?

Duplication doesn't feel very good at first sight. But maybe the module is small and stable enough that we can afford it.

TBH apollo-api module is stable, there were no major changes, just some small fixes. So I guess we can afford to support both.

do you mean we shouldn't pull the Kotlin stdlib for java users

Yeah, Java users will be frustrated about that (from what I saw in the conversation regarding OkHttp migration to Kotlin).

The main concern is how we can ensure bytecode compatibility required by runtime module.

Well, OkHttp is going for that and it is Apollo's biggest change to go Kotlin Multiplatform. Would you remove OkHttp dependency? If no, I am not sure if it really worth to go extra mile to support have that support.

I would suggest, that we could use KTor(https://ktor.io/) instead of OkHttp.

@sav007

Regarding

Java users will be frustrated about that (from what I saw in the conversation regarding OkHttp migration to Kotlin)

Can you share where I can find this conversation I am curious to know what makes java people frustrated 馃 ?

Based on the Okhttp documentation version 4.x is the same as 3.x expect with implementation language is Kotlin, not java, Won't this change make it compatible with k/n (Kotlin native) or not necessarily?

@Sarthak30
I wouldn't recommend to use Ktor for network at least for now. As Ktor is built on top of coroutines and as a result because of limitation coroutines work only within main thread, parsing of http response happens on main thread (at least on iOS last time I checked). What we should do is to try to abstract the network layer (transport layer) in such way where it easy to plug any network transport layer implementation.

@georgehadly-marleyspoon
Check the thread of https://github.com/square/okhttp/issues/4723

Based on the Okhttp documentation version 4.x is the same as 3.x expect with implementation language is Kotlin, not java,

Even it was guarantee that byte code will be identical to 3.x, I remember that changes to interceptor API implementation was a breaking changes at least on Kotlin side. But I guess the main point from Java community is that new version of OkHttp brings a dependency to Kotlin stdlib.

Anyway after investigations I don't see any other way except migrating apollo-api to Kotlin, as supporting both Kotlin and JVM version for api module and guarantee byte code compatibility is too much in effort.

Closing since the phase 1 is done 馃コ

serialize / deserialize models to / from raw JSON (we can utilize multi platform library such as Kotlinx Serialization for JSON support)

鈽濓笍this is also done by keeping our JSON serialization based on Okio types. Migrating to KotlinX Serialization could actually be a really good alternative. Let's open an issue to resolve that if necessary.

Was this page helpful?
0 / 5 - 0 ratings