Skip to content

Commit b5db319

Browse files
authored
Omit scalar definitions from SDL (#5132)
* omit scalars from SDL * keep toSDL() experimental
1 parent 6559b12 commit b5db319

File tree

6 files changed

+42
-35
lines changed

6 files changed

+42
-35
lines changed

libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/Schema.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package com.apollographql.apollo3.ast
22

33
import com.apollographql.apollo3.annotations.ApolloExperimental
44
import com.apollographql.apollo3.annotations.ApolloInternal
5-
import okio.Buffer
65

76
/**
87
* A wrapper around a schema [GQLDocument] that ensures the [GQLDocument] is valid and caches
@@ -49,7 +48,7 @@ class Schema internal constructor(
4948
fun toGQLDocument(): GQLDocument = GQLDocument(
5049
definitions = definitions,
5150
filePath = null
52-
).withoutBuiltinDefinitions()
51+
)
5352

5453
/**
5554
* @param name the current name of the directive (like "kotlin_labs__nonnull")
@@ -131,7 +130,7 @@ class Schema internal constructor(
131130
@ApolloInternal
132131
fun toMap(): Map<String, Any> {
133132
return mapOf(
134-
"sdl" to GQLDocument(definitions, sourceLocation = null).toUtf8(),
133+
"sdl" to GQLDocument(definitions, sourceLocation = null).toSDL(),
135134
"keyFields" to keyFields.mapValues { it.value.toList().sorted() },
136135
"foreignNames" to foreignNames,
137136
"directivesToStrip" to directivesToStrip,
@@ -217,7 +216,7 @@ class Schema internal constructor(
217216
@ApolloInternal
218217
fun fromMap(map: Map<String, Any>): Schema {
219218
return Schema(
220-
definitions = (map["sdl"] as String).parseAsGQLDocument().getOrThrow().definitions,
219+
definitions = combineDefinitions((map["sdl"] as String).parseAsGQLDocument().getOrThrow().definitions, builtinDefinitions(), ConflictResolution.TakeLeft),
221220
keyFields = (map["keyFields"]!! as Map<String, Collection<String>>).mapValues { it.value.toSet() },
222221
foreignNames = map["foreignNames"]!! as Map<String, String>,
223222
directivesToStrip = map["directivesToStrip"]!! as List<String>,

libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqldocument.kt

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,28 @@
11
package com.apollographql.apollo3.ast
22

3+
import com.apollographql.apollo3.annotations.ApolloDeprecatedSince
4+
import com.apollographql.apollo3.annotations.ApolloExperimental
35
import com.apollographql.apollo3.ast.internal.apollo_v0_1_definitionsStr
46
import com.apollographql.apollo3.ast.internal.apollo_v0_2_definitionsStr
57
import com.apollographql.apollo3.ast.internal.builtinsDefinitionsStr
6-
import com.apollographql.apollo3.annotations.ApolloDeprecatedSince
78
import com.apollographql.apollo3.ast.internal.linkDefinitionsStr
8-
import okio.Buffer
99

10+
/**
11+
* Add builtin definitions from the latest spec version to the [GQLDocument]
12+
*
13+
* SDL representations must skip scalars and may skip directive definitions. This function adds them back to form a full schema.
14+
*
15+
* If a definition already exists, it is kept as is
16+
*
17+
* Scalars: https://spec.graphql.org/draft/#sel-GAHXJHABAB_D4G
18+
* Directives: https://spec.graphql.org/draft/#sel-FAHnBPLCAACCcooU
19+
*/
1020
fun GQLDocument.withBuiltinDefinitions(): GQLDocument {
1121
return withDefinitions(builtinDefinitions())
1222
}
1323

24+
@Deprecated("Use GQLDocument.toSDL() to write a GQLDocument without the scalar directives")
25+
@ApolloDeprecatedSince(ApolloDeprecatedSince.Version.v4_0_0)
1426
fun GQLDocument.withoutBuiltinDefinitions(): GQLDocument {
1527
return withoutDefinitions(builtinDefinitions())
1628
}
@@ -99,17 +111,24 @@ internal fun combineDefinitions(left: List<GQLDefinition>, right: List<GQLDefini
99111

100112
return mergedDefinitions
101113
}
114+
private fun GQLDocument.withDefinitions(definitions: List<GQLDefinition>): GQLDocument {
115+
return copy(
116+
definitions = combineDefinitions(this.definitions, definitions, ConflictResolution.TakeLeft)
117+
)
118+
}
102119

103120
/**
104-
* Adds [definitions] to the [GQLDocument]
121+
* Outputs a schema document to SDL. For executable documents, use toUtf8()
105122
*
106-
* If a definition already exists, it is kept as is and a warning is logged
107-
* See https://spec.graphql.org/draft/#sel-FAHnBPLCAACCcooU
123+
* SDL representations must skip scalars definitions.
108124
*
109-
* A better implementation might verify that the definitions match or are compatible
125+
* See https://spec.graphql.org/draft/#sel-GAHXJHABAB_D4G
110126
*/
111-
private fun GQLDocument.withDefinitions(definitions: List<GQLDefinition>): GQLDocument {
112-
return copy(
113-
definitions = combineDefinitions(this.definitions, definitions, ConflictResolution.TakeLeft)
114-
)
127+
@ApolloExperimental
128+
fun GQLDocument.toSDL(indent: String = " "): String {
129+
return this.copy(
130+
definitions = definitions.filter {
131+
it !is GQLScalarTypeDefinition || it.name !in GQLTypeDefinition.builtInTypes
132+
}
133+
).toUtf8(indent)
115134
}

libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/gqlnode.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,3 @@ fun GQLNode.toUtf8(indent: String = " "): String {
1717
toUtf8(buffer, indent)
1818
return buffer.readUtf8()
1919
}
20-

libraries/apollo-ast/src/commonMain/kotlin/com/apollographql/apollo3/ast/introspection/introspection_to_schema.kt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,10 +315,6 @@ private class GQLDocumentBuilder(private val introspectionSchema: IntrospectionS
315315

316316
/**
317317
* Parses the [IntrospectionSchema] into a [GQLDocument]
318-
*
319-
* The returned [GQLDocument] does not contain any of the builtin definitions (scalars, directives, introspection)
320-
*
321-
* See https://spec.graphql.org/draft/#sel-GAHXJHABuCB_Dn6F
322318
*/
323319
@ApolloExperimental
324320
fun IntrospectionSchema.toGQLDocument(filePath: String? = null): GQLDocument = GQLDocumentBuilder(this, filePath)

libraries/apollo-ast/src/commonTest/kotlin/com/apollographql/apollo3/graphql/ast/test/SDLWriterTest.kt

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
package com.apollographql.apollo3.graphql.ast.test
22

3-
import com.apollographql.apollo3.ast.SDLWriter
4-
import com.apollographql.apollo3.ast.Schema
3+
import com.apollographql.apollo3.ast.GQLDocument
54
import com.apollographql.apollo3.ast.parseAsGQLDocument
6-
import com.apollographql.apollo3.ast.toSchema
7-
import com.apollographql.apollo3.ast.toUtf8
8-
import okio.Buffer
5+
import com.apollographql.apollo3.ast.toSDL
96
import kotlin.test.Test
107
import kotlin.test.assertEquals
118

129
class SDLWriterTest {
1310
@Test
14-
fun schemaMayContainBuiltinDirectives() {
11+
fun simpleTest() {
1512
val schemaString = """
1613
schema {
1714
query: Query
@@ -43,11 +40,9 @@ class SDLWriterTest {
4340
4441
""".trimIndent()
4542

46-
val schema: Schema = schemaString.toSchema()
47-
val writerBuffer = Buffer()
48-
val sdlWriter = SDLWriter(writerBuffer, " ")
49-
sdlWriter.write(schema.toGQLDocument())
50-
assertEquals(writerBuffer.readUtf8(), schemaString)
43+
val schema: GQLDocument = schemaString.parseAsGQLDocument().getOrThrow()
44+
val sdl = schema.toSDL(" ")
45+
assertEquals(schemaString, sdl)
5146
}
5247

5348
@Test
@@ -108,7 +103,7 @@ class SDLWriterTest {
108103

109104
val expected = schemaString.parseAsGQLDocument().getOrThrow()
110105

111-
val serialized = expected.toUtf8()
106+
val serialized = expected.toSDL()
112107

113108
serialized.parseAsGQLDocument().getOrThrow()
114109
// Enable when we have hashCode and equals on GQLNode

libraries/apollo-tooling/src/main/kotlin/com/apollographql/apollo3/tooling/SchemaDownloader.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ import com.apollographql.apollo3.ast.introspection.IntrospectionSchema
77
import com.apollographql.apollo3.ast.introspection.toGQLDocument
88
import com.apollographql.apollo3.ast.introspection.toIntrospectionSchema
99
import com.apollographql.apollo3.ast.introspection.writeTo
10+
import com.apollographql.apollo3.ast.toSDL
1011
import com.apollographql.apollo3.ast.toSchema
11-
import com.apollographql.apollo3.ast.toUtf8
1212
import com.apollographql.apollo3.exception.ApolloGraphQLException
1313
import com.apollographql.apollo3.network.okHttpClient
1414
import com.apollographql.apollo3.tooling.platformapi.public.DownloadSchemaQuery
1515
import kotlinx.coroutines.runBlocking
16-
import okio.Buffer
1716
import java.io.File
1817
import com.apollographql.apollo3.tooling.graphql.draft.IntrospectionQuery as GraphQLDraftIntrospectionQuery
1918
import com.apollographql.apollo3.tooling.graphql.june2018.IntrospectionQuery as GraphQLJune2018IntrospectionQuery
@@ -121,7 +120,7 @@ object SchemaDownloader {
121120
if (introspectionSchema == null) {
122121
check(sdlSchema != null)
123122
// Convert from SDL to JSON
124-
Buffer().writeUtf8(sdlSchema)
123+
sdlSchema
125124
.toSchema()
126125
.toIntrospectionSchema()
127126
.writeTo(schema)
@@ -134,7 +133,7 @@ object SchemaDownloader {
134133
if (sdlSchema == null) {
135134
check(introspectionSchema != null)
136135
// Convert from JSON to SDL
137-
schema.writeText(introspectionSchema.toGQLDocument().toUtf8(indent = " "))
136+
schema.writeText(introspectionSchema.toGQLDocument().toSDL(indent = " "))
138137
} else {
139138
// Copy SDL verbatim
140139
schema.writeText(sdlSchema)

0 commit comments

Comments
 (0)