Open manuel-mauky opened 7 years ago
Can we start working on this? It would be fantastic to have support of mutations.
I've spend some time thinking about this topic and I think the approach with the "SchemaEnhancer" function that I've proposed in the opening comment has some drawbacks and in my opinion we should think about another solution instead. In my opinion we have 2 major problems with the existing implementation:
GraphQLExecutor
creates it's own instance of GraphQLSchemaBuilder
. This makes it hard to extend the functionality from the outside.GraphQLSchemaBuilder
class has a wrong name and a wrong API in comparison to what it actually does. The only real responsibility of the class is to build a GraphQL query field definition for all JPA entities. So maybe a better name would be for example "JpaGraphQLQueryProvider".Let's think about this idea a little further: There could be other "QueryProviders" that generate query field definitions that are then put together to form the actual query type in the root of the schema. Similar to that there could be multiple "MutationProviders" implemented by the user of the library that form the mutation type of the schema.
With this approach we would need a new GraphQLSchemaBuilder
class that takes all available QueryProviders and MutationProviders and creates the actual schema. A similar approach is used in the graphql-java-servlet project.
With this type of API the user could define his mutations and also additional query types. There could even be third party libraries (like some Spring Boot magic) that creates the mutation definition based on some annotations.
The big question for me is: How do you wire these classes up at runtime? This could be implemented with some CDI magic that looks for all available implementations of QueryProvider
and MutationProvider
interfaces at runtime. But this would need a dependency to CDI which would be problematic in Spring projects.
At the moment I don't have a good idea of how this could me implemented.
Any update on this?
I created a pull request which resolved this. It's a temporary fix, but it should pave the way for better, more long-term solutions. To create a mutation you can write:
GraphQLExecutor executor = ...
GraphQLObject mutation = ...
GraphQLSchema.Builder builder = executor.getBuilder().mutation(mutation)
executor.updateSchema(builder)
At the moment the whole Schema is generated under the hood by the library without any way of editing it as developer. This way it's not possible to have mutations.
The reason for this is in
GraphQLSchemaBuilder
.getGraphQLSchema()`:This method is invoked by
GraphQLExecutor.createGraphQL()
:For testing I've changed this locally so that the
GraphQLSchemaBuilder
now also gets a "schemaEnhancer" function which can be used to "enhance" the schema. The function has the signatureBiConsumer<GraphQLSchema.Builder, EntityManager>
:This way I can provide a function to manipulate the schema after the query type is generated but before the actual schema is build. This way I can add mutations like this:
I need to pass through the enhancer function to the
GraphQLExecutor
and from there to theGraphQLSchemaBuilder
. In my test project I'm using Spring Boot and therefore have to configure the dependency injection accordingly.It works for me and I would be happy to provide a PullRequest. However, I'd like to discuss the approach beforehand because I'm not sure if this approach would work for environments other then Spring Boot and I'm not sure if the approach of passing an enhancer function is the best possible way. Maybe there is a better way that better uses dependency injection mechanisms?
EDIT: Another aspect is that there may be use cases where the developer likes to add or manipulate the query part of the Schema. At the moment this isn't possible and it wouldn't be possible with my proposes solution either because the creation of the query part of the Schema is hard coded. Maybe we could find a more flexible way of defining these kinds of things.