S.
11/13/2023, 7:37 PMDariusz Kuc
11/13/2023, 8:06 PMS.
11/13/2023, 8:08 PMDariusz Kuc
11/13/2023, 8:11 PMfun didBuildSchema(builder: GraphQLSchema.Builder): GraphQLSchema.Builder = builder
is the last hook that gives you access to the schema builder up to that point. There is no way to read out of the builder but you could build a schema and then transform it to add more stuff into it (thats what is done for federation)
*unsure whats your use case or what you are trying to do thereS.
11/13/2023, 8:20 PMDariusz Kuc
11/13/2023, 8:33 PMEither
type but it should be doable through the hooks .... but most likely you will need to manually provide the mappings
first thing that pops to mind is the willGenerateGraphQLType
hook -> https://github.com/ExpediaGroup/graphql-kotlin/blob/master/generator/graphql-kotli[…]iagroup/graphql/generator/internal/types/generateGraphQLType.kt
or willResolveMonad
hook (https://github.com/ExpediaGroup/graphql-kotlin/blob/master/generator/graphql-kotli[…]pediagroup/graphql/generator/internal/types/generateProperty.kt)S.
11/14/2023, 12:24 PMDariusz Kuc
11/14/2023, 3:12 PMEither
? you would have to map those left and right values
i don't think there is anything automated atm that you could useS.
11/14/2023, 9:27 PMDariusz Kuc
11/14/2023, 9:38 PMUser
type is already defined in the schema then I think you could just use GraphQLTypeReference
and graphql-java
will update the ref before providing final schemaS.
11/14/2023, 9:47 PMDariusz Kuc
11/14/2023, 9:48 PMS.
11/14/2023, 10:14 PMval graphqlDeckEither: GraphQLUnionType = GraphQLUnionType.newUnionType()
.name("DeckEither")
.possibleType(GraphQLTypeReference("Deck"))
.possibleType(GraphQLTypeReference("NotFound"))
.possibleType(GraphQLTypeReference("Unauthorized"))
.typeResolver { env ->
when (val value = env.getObject<Either<DomainError, Deck>>()) {
is arrow.core.Either.Left -> {
when (value.value) {
NotFound -> env.schema.getObjectType("NotFound")
Unauthorized -> env.schema.getObjectType("Unauthorized")
is Duplicate -> env.schema.getObjectType("Duplicate")
is InvalidInput -> env.schema.getObjectType("InvalidInput")
}
}
is arrow.core.Either.Right -> env.schema.getObjectType("Deck")
}
}
.build()
with this a union DeckEither = Deck | NotFound | Unauthorized
is created as expected.
querying returns the correct types however I'm getting Exception while fetching data (/getDeck/title) : object is not an instance of declaring class
when trying to access any properties of returned objectsDariusz Kuc
11/14/2023, 10:15 PMS.
11/15/2023, 4:24 PMclass CustomDataFetcher(private val propertyGetter: KProperty.Getter<*>) : DataFetcher<Any?> {
override fun get(environment: DataFetchingEnvironment): Any? {
environment.getSource<Any?>().let { source ->
return propertyGetter.call(getSourceValue(source))
}
}
private fun getSourceValue(source: Any?): Any? = when (source) {
is Either.Right<*> -> source.value
is Either.Left<*> -> source.value
else -> source
}
}
class DataFetcherFactoryProvider : SimpleKotlinDataFetcherFactoryProvider() {
override fun propertyDataFetcherFactory(kClass: KClass<*>, kProperty: KProperty<*>): DataFetcherFactory<Any?> =
DataFetcherFactory {
CustomDataFetcher(kProperty.getter)
}
}
Thank you very much for your help!Dariusz Kuc
11/15/2023, 4:27 PMS.
11/15/2023, 5:49 PMCaused by: java.lang.NullPointerException
at graphql.com.google.common.base.Preconditions.checkNotNull(Preconditions.java:903)
at graphql.com.google.common.collect.ImmutableList$Builder.add(ImmutableList.java:815)
at graphql.collect.ImmutableKit.map(ImmutableKit.java:56)
at graphql.schema.GraphQLTypeResolvingVisitor.visitGraphQLUnionType(GraphQLTypeResolvingVisitor.java:38)
at graphql.schema.GraphQLUnionType.accept(GraphQLUnionType.java:185)
at graphql.schema.SchemaTraverser$TraverserDelegateVisitor.enter(SchemaTraverser.java:111)
at graphql.util.Traverser.traverse(Traverser.java:144)
at graphql.schema.SchemaTraverser.doTraverse(SchemaTraverser.java:98)
at graphql.schema.SchemaTraverser.depthFirst(SchemaTraverser.java:88)
at graphql.schema.SchemaTraverser.depthFirst(SchemaTraverser.java:81)
at graphql.schema.impl.SchemaUtil.replaceTypeReferences(SchemaUtil.java:105)
at graphql.schema.GraphQLSchema$Builder.buildImpl(GraphQLSchema.java:938)
at graphql.schema.GraphQLSchema$Builder.build(GraphQLSchema.java:904)
at com.expediagroup.graphql.generator.SchemaGenerator.generateSchema(SchemaGenerator.kt:88)
at com.expediagroup.graphql.generator.SchemaGenerator.generateSchema$default(SchemaGenerator.kt:58)
at com.expediagroup.graphql.generator.ToSchemaKt.toSchema(toSchema.kt:43)
at com.expediagroup.graphql.plugin.schema.GenerateSDLKt.generateSDL(GenerateSDL.kt:97)
at com.expediagroup.graphql.plugin.gradle.actions.GenerateSDLAction.execute(GenerateSDLAction.kt:38)
Dariusz Kuc
11/15/2023, 5:51 PMS.
11/15/2023, 5:53 PMDariusz Kuc
11/15/2023, 5:54 PMS.
11/15/2023, 6:42 PMwillBuildSchema
hook (https://github.com/ExpediaGroup/graphql-kotlin/blob/716809e6a1842e36516c093cd848cd[…]om/expediagroup/graphql/generator/hooks/SchemaGeneratorHooks.kt) but it doesn't seem to be picked up eitherDariusz Kuc
11/15/2023, 6:49 PMS.
11/15/2023, 6:50 PMDariusz Kuc
11/15/2023, 7:01 PMS.
11/15/2023, 7:06 PMDariusz Kuc
11/15/2023, 7:06 PMS.
11/15/2023, 7:20 PMfun debugUser(): User? = null
`) for all possible union types - so doing this it worksDariusz Kuc
11/15/2023, 7:35 PMS.
11/15/2023, 8:10 PMdidGenerateQueryObject
as well as in didBuildSchema
but it always results in the same NPEDariusz Kuc
11/15/2023, 9:09 PMS.
11/15/2023, 9:10 PMDariusz Kuc
11/15/2023, 9:11 PMS.
11/15/2023, 9:16 PMDariusz Kuc
11/15/2023, 9:19 PMIf I simply could remove those queries before passing the schema on to the user (introspection or sdl) I could live with ityou definitely should be able to do it in
didBuildSchema
-> pseudocode
val originalSchema = builder.build()
return originalSchema.transform {
// remove the fields
}
S.
11/15/2023, 9:25 PMprivate var queryType: GraphQLObjectType? = null
override fun didGenerateQueryObject(type: GraphQLObjectType): GraphQLObjectType {
queryType = GraphQLObjectType.newObject()
.name(type.name)
.withAppliedDirectives(*type.appliedDirectives.toTypedArray())
.fields(type.fieldDefinitions.filter { !it.name.contains("debug") })
.build()
return super.didGenerateQueryObject(type)
}
override fun didBuildSchema(builder: GraphQLSchema.Builder): GraphQLSchema.Builder {
builder.query(queryType)
return super.didBuildSchema(builder)
}
(didGenerateQueryObject because I don't see a way to retrieve queryType from the Builder)Dariusz Kuc
11/15/2023, 9:30 PMoverride fun didBuildSchema(builder: GraphQLSchema.Builder): GraphQLSchema.Builder {
val originalSchema = builder.build()
val filteredQueries = originalSchema.queryType.fields.filter { it.name != "foo" }
builder.query(originalSchema.queryType.transform {
it.replaceFields(filteredQueries)
})
return builder
}
val originalSchema = builder.build()
<=== this would fail if there are some unresolved type references
that being said even with your filtering on the didGenerateQueryObject
the result "should" be the same (as the types should already be processed at that time) -> there is some weird ordering issue going on thereS.
11/15/2023, 9:38 PMDariusz Kuc
11/15/2023, 9:41 PMEither
queries then you end up with references onlydebug
queries you should get the types registered so it "should" be safe to remove those queries ... yet it blows up so something is off in how those types are addedoverride fun didBuildSchema(builder: GraphQLSchema.Builder): GraphQLSchema.Builder {
val originalSchema = builder.build()
val filteredQueries = originalSchema.queryType.fields.filter { it.name != "foo" }
val modifiedQuery = originalSchema.queryType.transform {
it.replaceFields(filteredQueries)
}
return GraphQLSchema.newSchema(originalSchema).query(modifiedQuery)
}
but it doesn't solve the underlying issueS.
11/15/2023, 9:50 PMDariusz Kuc
11/15/2023, 9:55 PMS.
11/15/2023, 9:56 PMDariusz Kuc
11/15/2023, 9:57 PMS.
11/15/2023, 10:25 PMdebug..
queries in BookQueryService is what breaks or fixes itDariusz Kuc
11/16/2023, 5:44 AMS.
11/16/2023, 11:29 AM