apollographql / apollo-kotlin

:rocket:  A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
https://www.apollographql.com/docs/kotlin
MIT License
3.73k stars 653 forks source link

Which multiplatform architectural pattern should I use or build ? #3106

Closed ajacquierbret closed 2 months ago

ajacquierbret commented 3 years ago

I'm looking for the best (if such thing exists) architectural pattern that would fit with the way apollo handles caching.

I looked at many implementations of different patterns in KMM/KMP, such as MVI, MVVM, VIPER, etc. but they all provide a very thick abstraction layer on the state management, which was to be expected of course. But the app I'm developing being highly dependant on graphql, I can't look away from apollo-graphql, which was my go-to coming from the React Native world (btw, kudos to the Apollo team for the Apollo React client !)

But of course, the state management of these architectural pattern sounds like it will clash with the Apollo cache.

I'm looking for something quite unique and I don't think such implementation already exists due to the newness of KMP, but I'm not opposed to building it on my own. Anyway, here's some key features I'd like to see in such architecture :

I know it sounds like a big project, and it is. Of course I don't think anyone built something like that, mostly because it is highly tight to the Apollo client. I'd be up to building it on my own, but I'd like to get some feedbacks/clues/thoughts on how such an architecture should be implemented, and even if it's relevant to do something like that.

NB: I'm fairly new to Kotlin & KMP, I come from the fully cross-platform JS mobile world (mostly React Native).

Thanks in advance for your answers.

martinbonnin commented 3 years ago

Hi 👋 . That's something that I'd love to investigate. The reactive nature of the Normalized Cache coupled with declarative frameworks like SwiftUI and Compose could do wonders. I wrote a bit about it there. Most of the compose APIs have changed since that post was written but the concepts stay the same.

All in all, I think some of the building blocks are there:

Some still need to be done like IDE tooling, testability and navigation (does that last one need to know anything about GraphQL?). Also we could imagine some "glue" to handle common boilerplate code such as loading states, not really sure how that would look like.

If you haven't already, I can only recommend taking a look at https://github.com/joreilly/MortyComposeKMM from @joreilly that contains a state of the art multiplatform GraphQL + Compose + SwiftUI app and would be a nice starting point to write such an app.

Let's keep this issue open for general discussion, do not hesitate to open separate, more specific ones for the individual items.

ajacquierbret commented 3 years ago

Hi! Thanks a lot for your answer.

I'll maybe try to build an app that resembles most of the key features listed above, and see what should be abstracted by the hypothetical library/framework. I could then push it on a public repo so that anyone can make suggestions about implementation details. I think it'd be a good starting point to later isolate reusable or boilerplate code in a separate package until we get a very lean and minimal app, in which all of these key features are outsourced. What do you think of it?

Before I dive into this work, could you please confirm which apollo-android features aren't currently multiplatform ready? Essentially thinking about caching features.

Also, I may found what could be our pluggable-UI/lifecycle-aware components layer in this library. If I read it well, developers could "just" write platform-specific UIs that trigger graphql related operations defined inside the shared module (via library's BLoCs). It also satisfies the navigation routing and components logic testability features. Combined with the Apollo normalized cache, I guess it could be very powerful.

martinbonnin commented 3 years ago

Sounds great! To have multiplatform cache support, you'll have to use the 3.x developer previews. They're available in the com.apollographql.apollo3 maven group. As of speaking, the latest version is com.apollographql.apollo3:apollo-runtime-kotlin:3.0.0-dev10. There's not a lot of documentation yet but feel free to ask questions here or in the apollo-android slack channel on kotlinlang. The dev-3.x branch has a unified runtime between JVM and Kotlin and supports everything from the main branch with the exception of HTTP cache and Java codegen.

I think it'd be a good starting point to later isolate reusable or boilerplate code in a separate package until we get a very lean and minimal app, in which all of these key features are outsourced.

Sounds good 👍 . We can see as we go what can be upstreamed vs what is too specific.

Also, I may found what could be our pluggable-UI/lifecycle-aware components layer in this library.

Never used Decompose myself but will take a look, looks promising!

martinbonnin commented 2 months ago

Closing as stale. Please leave a comment if you want us to reopen.