Skip to content

Commit c65f2a1

Browse files
authored
[federation] use federation-jvm ServiceSDLPrinter (ExpediaGroup#1546)
Updated `FederatedSchemaGeneratorHooks` to use `ServiceSDLPrinter` provided by the `federation-jvm` in favor of our custom printer logic.
1 parent 095b056 commit c65f2a1

File tree

3 files changed

+48
-21
lines changed

3 files changed

+48
-21
lines changed

generator/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/generator/federation/FederatedSchemaGeneratorHooks.kt

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616

1717
package com.expediagroup.graphql.generator.federation
1818

19+
import com.apollographql.federation.graphqljava.printer.ServiceSDLPrinter.generateServiceSDL
20+
import com.apollographql.federation.graphqljava.printer.ServiceSDLPrinter.generateServiceSDLV2
1921
import com.expediagroup.graphql.generator.annotations.GraphQLName
20-
import com.expediagroup.graphql.generator.directives.DEPRECATED_DIRECTIVE_NAME
2122
import com.expediagroup.graphql.generator.directives.DirectiveMetaInformation
22-
import com.expediagroup.graphql.generator.extensions.print
2323
import com.expediagroup.graphql.generator.federation.directives.EXTENDS_DIRECTIVE_TYPE
2424
import com.expediagroup.graphql.generator.federation.directives.EXTERNAL_DIRECTIVE_TYPE
2525
import com.expediagroup.graphql.generator.federation.directives.FEDERATION_SPEC_URL
@@ -61,18 +61,13 @@ import graphql.schema.GraphQLDirective
6161
import graphql.schema.GraphQLObjectType
6262
import graphql.schema.GraphQLSchema
6363
import graphql.schema.GraphQLType
64-
import java.util.function.Predicate
6564
import kotlin.reflect.KType
6665
import kotlin.reflect.full.findAnnotation
6766

6867
/**
6968
* Hooks for generating federated GraphQL schema.
7069
*/
7170
open class FederatedSchemaGeneratorHooks(private val resolvers: List<FederatedTypeResolver<*>>, private val optInFederationV2: Boolean = false) : SchemaGeneratorHooks {
72-
private val scalarDefinitionRegex = "(^\".+\"$[\\r\\n])?^scalar (_FieldSet|_Any)$[\\r\\n]*".toRegex(setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE))
73-
private val emptyQueryRegex = "^type Query @extends \\s*\\{\\s*}\\s*".toRegex(setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE))
74-
private val serviceFieldRegex = "\\s*_service: _Service!".toRegex(setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE))
75-
private val serviceTypeRegex = "^type _Service\\s*\\{\\s*sdl: String!\\s*}\\s*".toRegex(setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE))
7671
private val validator = FederatedSchemaValidator()
7772

7873
private val federationV2OnlyDirectiveNames: Set<String> = setOf(
@@ -206,17 +201,11 @@ open class FederatedSchemaGeneratorHooks(private val resolvers: List<FederatedTy
206201
* https://www.apollographql.com/docs/apollo-server/federation/federation-spec/#query_service
207202
*/
208203
private fun getFederatedServiceSdl(schema: GraphQLSchema): String {
209-
val directivesToInclude: List<String> = federatedDirectiveList().map { it.name }.plus(DEPRECATED_DIRECTIVE_NAME)
210-
val customDirectivePredicate: Predicate<String> = Predicate { directivesToInclude.contains(it) }
211-
return schema.print(
212-
includeDefaultSchemaDefinition = optInFederationV2,
213-
includeDirectiveDefinitions = false,
214-
includeDirectivesFilter = customDirectivePredicate
215-
).replace(scalarDefinitionRegex, "")
216-
.replace(serviceFieldRegex, "")
217-
.replace(serviceTypeRegex, "")
218-
.replace(emptyQueryRegex, "")
219-
.trim()
204+
return if (optInFederationV2) {
205+
generateServiceSDLV2(schema)
206+
} else {
207+
generateServiceSDL(schema, false)
208+
}
220209
}
221210

222211
/**

generator/graphql-kotlin-federation/src/test/kotlin/com/expediagroup/graphql/generator/federation/execution/ServiceQueryResolverTest.kt

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ import kotlin.test.assertNotNull
3939
// SDL is returned without _entity and _service queries
4040
const val FEDERATED_SERVICE_SDL =
4141
"""
42+
schema {
43+
query: Query
44+
}
45+
4246
interface Product @extends @key(fields : "id") @key(fields : "upc") {
4347
id: String! @external
4448
reviews: [Review!]!
@@ -54,6 +58,8 @@ type Book implements Product @extends @key(fields : "id") @key(fields : "upc") {
5458
weight: Float! @external
5559
}
5660
61+
type Query @extends
62+
5763
type Review {
5864
body: String!
5965
content: String @deprecated(reason : "no longer supported, replace with use Review.body instead")
@@ -75,6 +81,10 @@ scalar CustomScalar"""
7581

7682
const val BASE_SERVICE_SDL =
7783
"""
84+
schema {
85+
query: Query
86+
}
87+
7888
type Query @extends {
7989
getSimpleNestedObject: [SelfReferenceObject]!
8090
hello(name: String!): String!
@@ -93,6 +103,23 @@ schema @link(url : "https://specs.apollo.dev/link/v1.0/") @link(import : ["exten
93103
query: Query
94104
}
95105
106+
directive @custom on SCHEMA | SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
107+
108+
"Marks target object as extending part of the federated schema"
109+
directive @extends on OBJECT | INTERFACE
110+
111+
"Marks target field as external meaning it will be resolved by federated schema"
112+
directive @external on FIELD_DEFINITION
113+
114+
"Space separated list of primary keys needed to access federated object"
115+
directive @key(fields: _FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE
116+
117+
"Specifies the base type field set that will be selectable by the gateway"
118+
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
119+
120+
"Specifies required input field set from the base type for a resolver"
121+
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
122+
96123
interface Product @extends @key(fields : "id", resolvable : true) @key(fields : "upc", resolvable : true) {
97124
id: String! @external
98125
reviews: [Review!]!
@@ -112,8 +139,12 @@ type CustomScalar {
112139
value: String!
113140
}
114141
142+
type Query @extends {
143+
_service: _Service!
144+
}
145+
115146
type Review {
116-
body: String!
147+
body: String! @custom
117148
content: String @deprecated(reason : "no longer supported, replace with use Review.body instead")
118149
customScalar: CustomScalar!
119150
id: String!
@@ -123,6 +154,13 @@ type User @extends @key(fields : "userId", resolvable : true) {
123154
name: String! @external
124155
userId: Int! @external
125156
}
157+
158+
type _Service {
159+
sdl: String!
160+
}
161+
162+
"Federation type representing set of fields"
163+
scalar _FieldSet
126164
"""
127165

128166
class ServiceQueryResolverTest {

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ kotlinxSerializationVersion = 1.3.2
2222

2323
androidPluginVersion = 7.1.2
2424
classGraphVersion = 4.8.149
25-
federationGraphQLVersion = 2.0.4
26-
graphQLJavaVersion = 19.1
25+
federationGraphQLVersion = 2.0.7
26+
graphQLJavaVersion = 19.2
2727
graphQLJavaDataLoaderVersion = 3.2.0
2828
jacksonVersion = 2.13.3
2929
# KotlinPoet v1.12.0+ requires Kotlin v1.7

0 commit comments

Comments
 (0)