Gary Madden
Gary Madden

Reputation: 103

Programatically specifying the GraphQL schema in Spring boot

I'm using a 'code first' approach for defining the schema using graphql-java-annotations instead of defining the schema in a separate .graphqls file.

I'm trying to specify the schema by using GraphQlSourceBuilderCustomizer as mentioned in the documentation but I get the following exception:

org.springframework.graphql.execution.MissingSchemaException: No GraphQL schema definition was configured. at [email protected]/java.util.Optional.orElseThrow(Optional.java:403) at app//org.springframework.graphql.execution.DefaultGraphQlSourceBuilder.build(DefaultGraphQlSourceBuilder.java:136) at app//org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration.graphQlSource(GraphQlAutoConfiguration.java:90)

Here's my configuration class. Does anyone know where I'm going wrong?

@Configuration
public class GraphQLConfiguration {
    @Bean
    public GraphQlSourceBuilderCustomizer sourceBuilderCustomizer() {
        GraphQLSchema graphQLSchema = AnnotationsSchemaCreator.newAnnotationsSchema()
                .query(GraphQLQuery.class)
                .build();

        return graphQlSourceBuilder -> graphQlSourceBuilder.configureGraphQl(graphQLBuilder -> graphQLBuilder.schema(graphQLSchema));
    }
}

Upvotes: 4

Views: 1324

Answers (1)

Lewis Munene
Lewis Munene

Reputation: 164

Going by the answers to this question, it's clear that Spring-Graphql demands a schema.graphqls file with a valid schema or it will not load.

There are two possible work-arounds:

  1. Creating a dummy ".graphqls" file in your resources folder and adding a dummy type there
  2. Provide an in-memory graphql definition with a dummy type

Option #1 is easy, so I will give sample code for Option #2:

@Bean
@Lazy
@ConditionalOnBean({GraphQLSchema.class, DataFetcherExceptionHandler.class})
public GraphQlSourceBuilderCustomizer federationTransform(GraphQLSchema schema,
                                                          DataFetcherExceptionHandler exceptionHandler) {
    String ss = """
            type Meta {
                count: Int
            }
            type Query {
                NotificationsMeta: Meta
            }
            """;
    return builder -> {
        URL schemaUrl = InMemoryURLFactory.getInstance().build("/graphql.schema", ss);

        builder.schemaResources(new UrlResource(schemaUrl));
        builder.configureGraphQl(graphQLBuilder -> graphQLBuilder.schema(schema)
                .defaultDataFetcherExceptionHandler(exceptionHandler));
    };
}

With this, the in-memory schema is ignored and the schema represented by the GraphQLSchema object is used instead. NB: InMemoryURLFactory can be obtained from this Stack Overflow answer

Upvotes: 0

Related Questions