Stylianos Gakis
09/14/2023, 10:52 AMrunBocking
and go from there, which should probably be fine in the context of spring-mvc anyway I think, but I might need to look more into this one
◦ suspendCancellableCoroutine
then if we need to bridge the gap from corotuines -> blocking code so the other way around
• The default HTTP client is OkHttp, I see that ktor is also something that can be used, maybe only in 4.x? Seen in a discussion here, don’t know more details. Is there a way to provide your own implementation completely anyway? And let them wire it up with the existing client (whatever is given to them by Spring there) they’re using anyway, just to do the HTTP part of this?
• To make their life easier, should we perhaps look into using apollo-api only, and not bring in any of the rest of the library, so that we can get the super convenient parts of the type-safe auto-generated code but need to do the rest of the wiring ourselves?
Have you had this discussion with anyone else before perhaps? What approach did they go with in the end?Stylianos Gakis
09/14/2023, 10:57 AMApolloClient
basically.mbonnin
09/14/2023, 12:16 PMrunBlocking{}
or apollo-api
. apollo-api
will give them more control at the cost of some features missing. But maybe they don't need those features?
(BTW, there's a doc about using the models directly here)mbonnin
09/14/2023, 12:17 PMStylianos Gakis
09/14/2023, 1:19 PMfun asd() {
val query: giraffe.ChargeHistoryQuery = ChargeHistoryQuery()
val body: String = buildJsonString {
query.composeJsonRequest(this, CustomScalarAdapters.Empty)
}
val httpResponse: Response = sendHttpRequestWithYourFavoriteHttpClient(body, "application/json")
val jsonResponse: JsonReader = httpResponse.body!!.source().buffer.jsonReader()
val result: ApolloResponse<ChargeHistoryQuery.Data> = query.parseJsonResponse(jsonResponse, CustomScalarAdapters.Empty)
val data: ChargeHistoryQuery.Data = result.dataAssertNoErrors
}
// This would be quite similar with their own HttpClient I presume
fun sendHttpRequestWithYourFavoriteHttpClient(body: String, mediaType: String): Response {
return OkHttpClient.Builder().build()
.newCall(
Request.Builder()
.post(body.toRequestBody(mediaType.toMediaType()))
.build()
)
.execute()
}
The only thing that is easy here that may not be for them is that OkHttp gives you an easy way to get the response into an okio buffer with source().buffer
, which may not be as simple for whatever they use.
And also no way to not bring in the okio dependency since apollo-api uses it. Which I don’t think would be an issue by itself I’ll see what they think though. It’s just that it may not be 100% intuitive to work with directly from personal experience, at least not the first time you encounter it and I don’t think they’ve used it in the past.mbonnin
09/14/2023, 1:20 PMStylianos Gakis
09/14/2023, 1:20 PMApolloClient
land, and therefore need to somehow work with coroutines, which I feel like might be too much for them 😅Stylianos Gakis
09/14/2023, 1:21 PMmbonnin
09/14/2023, 1:21 PMapollo-api
is the easiest and less risky choice there, the dependencies are very minimalmbonnin
09/14/2023, 1:21 PMmbonnin
09/14/2023, 1:21 PMInputStream
/`OutputStream`mbonnin
09/14/2023, 1:23 PMinputStream.source().buffer()
outputStream.sink().buffer()
That should cover 90% of the use cases I think if they have input/output streams?Stylianos Gakis
09/14/2023, 1:24 PMStylianos Gakis
09/14/2023, 1:29 PM... same code
val inputStream: InputStream = sendHttpRequestWithYourFavoriteHttpClient(body, "application/json")
val jsonResponse: JsonReader = inputStream.source().buffer().jsonReader()
... same code
where their impl will have a return type of InputStream
which would be this impl with okhttp
fun sendHttpRequestWithYourFavoriteHttpClient(body: String, mediaType: String): InputStream {
return OkHttpClient.Builder().build()
.newCall(
Request.Builder()
.post(body.toRequestBody(mediaType.toMediaType()))
.build(),
)
.execute()
.body!!
.byteStream()
}
but the return type of InputStream is the important bit hereStylianos Gakis
09/14/2023, 2:34 PMmbonnin
09/14/2023, 2:38 PMapollo-runtime-java
is there. It's duplicating most of the runtime to not use coroutinesStylianos Gakis
09/14/2023, 2:39 PMmbonnin
09/14/2023, 2:39 PMStylianos Gakis
09/14/2023, 2:40 PMmbonnin
09/14/2023, 2:41 PMStylianos Gakis
09/14/2023, 2:44 PMmbonnin
09/14/2023, 2:46 PMmbonnin
09/14/2023, 2:48 PMBesides lacking caching support, should it at least in theory do everything else?What I'm trying to figure out here is what else there is besides caching. At the end of the day, sounds like
apollo-runtime-java
= apollo-api
+ OkHttp setup + Subscriptions/Websocketsmbonnin
09/14/2023, 2:51 PMStylianos Gakis
09/14/2023, 2:54 PMmbonnin
09/14/2023, 2:58 PMapollo-api
is the corner stone of Apollo and has a small API surface. apollo-api
isn't going anywhere and allows to use your HTTP client of choice (because none is provided by default).
apollo-runtime-java
comes with a much bigger API footprint and is not battle tested at all. The good thing is that it has some resemblance to the Kotlin runtime but it might also be a bad thing because it's not 1:1 the same implementation.
All in all, I'd say apollo-api
is a safe bet. If they want to try new stuff and give us feedback, have them try apollo-runtime-java
but this might change more than apollo-api
Stylianos Gakis
09/14/2023, 3:00 PMmbonnin
09/14/2023, 3:01 PM