Skip to content

Commit

Permalink
[🏃runtime] Allow buildPostBody to write operation extensions (#5630)
Browse files Browse the repository at this point in the history
* allow buildPostBody to write operation extensions

* update apiDump
  • Loading branch information
martinbonnin committed Feb 20, 2024
1 parent f301e9b commit 3e488f5
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 30 deletions.
1 change: 1 addition & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions libraries/apollo-api/api/apollo-api.api
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,7 @@ public final class com/apollographql/apollo3/api/http/DefaultHttpRequestComposer
public final class com/apollographql/apollo3/api/http/DefaultHttpRequestComposer$Companion {
public final fun appendQueryParameters (Ljava/lang/String;Ljava/util/Map;)Ljava/lang/String;
public final fun buildParamsMap (Lcom/apollographql/apollo3/api/Operation;Lcom/apollographql/apollo3/api/CustomScalarAdapters;ZZ)Lokio/ByteString;
public final fun buildPostBody (Lcom/apollographql/apollo3/api/Operation;Lcom/apollographql/apollo3/api/CustomScalarAdapters;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lcom/apollographql/apollo3/api/http/HttpBody;
public final fun buildPostBody (Lcom/apollographql/apollo3/api/Operation;Lcom/apollographql/apollo3/api/CustomScalarAdapters;ZLjava/lang/String;)Lcom/apollographql/apollo3/api/http/HttpBody;
public final fun composePayload (Lcom/apollographql/apollo3/api/ApolloRequest;)Ljava/util/Map;
public final fun getHEADER_ACCEPT_NAME ()Ljava/lang/String;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class DefaultHttpRequestComposer(
@Deprecated("If needed, add this header with ApolloCall.addHttpHeader() instead", level = DeprecationLevel.ERROR)
@ApolloDeprecatedSince(ApolloDeprecatedSince.Version.v4_0_0)
val HEADER_APOLLO_OPERATION_ID = "X-APOLLO-OPERATION-ID"

@Deprecated("If needed, add this header with ApolloCall.addHttpHeader() instead", level = DeprecationLevel.ERROR)
@ApolloDeprecatedSince(ApolloDeprecatedSince.Version.v4_0_0)
val HEADER_APOLLO_OPERATION_NAME = "X-APOLLO-OPERATION-NAME"
Expand Down Expand Up @@ -123,8 +124,8 @@ class DefaultHttpRequestComposer(
writer: JsonWriter,
operation: Operation<D>,
customScalarAdapters: CustomScalarAdapters,
sendApqExtensions: Boolean,
query: String?,
extensionsWriter: (JsonWriter.() -> Unit),
): Map<String, Upload> {
val uploads: Map<String, Upload>
writer.writeObject {
Expand All @@ -143,19 +144,37 @@ class DefaultHttpRequestComposer(
value(query)
}

extensionsWriter()
}

return uploads
}

private fun <D : Operation.Data> composePostParams(
writer: JsonWriter,
operation: Operation<D>,
customScalarAdapters: CustomScalarAdapters,
sendApqExtensions: Boolean,
query: String?,
): Map<String, Upload> {
return composePostParams(
writer, operation, customScalarAdapters, query, apqExtensionsWriter(operation.id(), sendApqExtensions)
)
}

private fun apqExtensionsWriter(id: String, sendApqExtensions: Boolean): JsonWriter.() -> Unit {
return {
if (sendApqExtensions) {
name("extensions")
writeObject {
name("persistedQuery")
writeObject {
name("version").value(1)
name("sha256Hash").value(operation.id())
name("sha256Hash").value(id)
}
}
}
}

return uploads
}

/**
Expand Down Expand Up @@ -224,11 +243,22 @@ class DefaultHttpRequestComposer(
}
}

@Deprecated("Use buildPostBody(operation, customScalarADapters, query, extensionsWriter) instead")
@ApolloDeprecatedSince(ApolloDeprecatedSince.Version.v4_0_0)
fun <D : Operation.Data> buildPostBody(
operation: Operation<D>,
customScalarAdapters: CustomScalarAdapters,
autoPersistQueries: Boolean,
query: String?,
): HttpBody {
return buildPostBody(operation, customScalarAdapters, query, apqExtensionsWriter(operation.id(), autoPersistQueries))
}

fun <D : Operation.Data> buildPostBody(
operation: Operation<D>,
customScalarAdapters: CustomScalarAdapters,
query: String?,
extensionsWriter: JsonWriter.() -> Unit,
): HttpBody {
val uploads: Map<String, Upload>

Expand All @@ -237,8 +267,8 @@ class DefaultHttpRequestComposer(
this,
operation,
customScalarAdapters,
autoPersistQueries,
query
query,
extensionsWriter,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package test

import com.apollographql.apollo3.ApolloClient
import com.apollographql.apollo3.api.ApolloRequest
import com.apollographql.apollo3.api.CustomScalarAdapters
import com.apollographql.apollo3.api.Operation
import com.apollographql.apollo3.api.http.ByteStringHttpBody
import com.apollographql.apollo3.api.http.DefaultHttpRequestComposer
import com.apollographql.apollo3.api.http.HttpMethod
import com.apollographql.apollo3.api.http.HttpRequest
import com.apollographql.apollo3.api.http.HttpRequestComposer
import com.apollographql.apollo3.api.json.buildJsonByteString
import com.apollographql.apollo3.api.json.jsonReader
import com.apollographql.apollo3.api.json.readAny
import com.apollographql.apollo3.api.json.writeObject
import com.apollographql.apollo3.integration.normalizer.HeroNameQuery
import com.apollographql.apollo3.integration.fullstack.LaunchDetailsQuery
import com.apollographql.apollo3.mockserver.MockServer
import com.apollographql.apollo3.mockserver.awaitRequest
import com.apollographql.apollo3.mockserver.enqueueString
Expand All @@ -24,51 +24,49 @@ import kotlin.test.assertEquals
class WithExtensionsHttpRequestComposer(private val serverUrl: String) : HttpRequestComposer {
override fun <D : Operation.Data> compose(apolloRequest: ApolloRequest<D>): HttpRequest {

return HttpRequest.Builder(HttpMethod.Post, serverUrl)
val request = HttpRequest.Builder(HttpMethod.Post, serverUrl)
.body(
ByteStringHttpBody(
"application/json",
buildJsonByteString {
writeObject {
name("query")
value(apolloRequest.operation.document())
name("operationName")
value(apolloRequest.operation.name())
name("extensions")
value("extension value")
}
}
)
DefaultHttpRequestComposer.buildPostBody(
apolloRequest.operation,
apolloRequest.executionContext[CustomScalarAdapters]!!,
apolloRequest.operation.document(),
) {
name("extensions")
writeObject {
name("key")
value("value")
}
}
)
.build()

return request
}
}

class BodyExtensionsTest {
@Suppress("UNCHECKED_CAST")
@Test
fun bodyExtensions() = runTest {
val mockServer = MockServer()
val serverUrl = mockServer.url()

val apolloClient = ApolloClient.Builder()
.networkTransport(
HttpNetworkTransport.Builder()
.httpRequestComposer(WithExtensionsHttpRequestComposer(serverUrl))
.httpRequestComposer(WithExtensionsHttpRequestComposer(mockServer.url()))
.build()
)
.build()

mockServer.enqueueString(statusCode = 500)
kotlin.runCatching {
apolloClient.query(HeroNameQuery())
.execute()
}
apolloClient.query(LaunchDetailsQuery("42")).execute()

val request = mockServer.awaitRequest()

@Suppress("UNCHECKED_CAST")
val asMap = Buffer().write(request.body).jsonReader().readAny() as Map<String, Any>
assertEquals(asMap["extensions"], "extension value")
assertEquals((asMap["extensions"] as Map<String, Any>).get("key"), "value")
assertEquals((asMap["variables"] as Map<String, Any>).get("id"), "42")

apolloClient.close()
mockServer.close()
Expand Down

0 comments on commit 3e488f5

Please sign in to comment.