Is it possible to dynamically create a GraphQL schema ?
We store the data in mongoDB and there is a possibility of new fields getting added. We do not want any code change to happen for this newly added field in the mongoDB document.
Is there any way we can generate the schema dynamically ?
Schema is defined in code, but for java(schema as pojo), when new
attribute is added, you have to update and recompile code, then
archive and deploy the jar again. Any way to generate schema by the
data instead of pre-define it?
Currently we are using java related projects (graphql-java, graphql-java-annotations) for GraphQL development.
2 Answers
You could use graphql-spqr (or the related Spring Boot starter, if applicable), it allows you auto-generate a schema based on your service classes. In your case, it would look like this:
public class Pojo {
private Long id;
private String name;
// whatever Ext is, any (complex) object would work fine
private List<Ext> exts;
}
public class Ext {
public String something;
public String somethingElse;
}
Presumably, you have a service class containing your business logic:
public class PojoService {
//this could also return List<Pojo> or whatever is applicable
@GraphQLQuery(name = "pojo")
public Pojo getPojo() {...}
}
To expose this service, you’d just do the following:
GraphQLSchema schema = new GraphQLSchemaGenerator()
.withOperationsFromSingleton(new PojoService())
.generate();
You could then fire a query such as:
query test {
pojo {
id
name
exts {
something
somethingElse
} } }
No need for strange wrappers or custom code of any kind, nor sacrificing type safety. Works with generics, dependency injection, or any other jazz you may have in your project.
Full disclosure: I’m the author of graphql-spqr.
3
-
please, can you help with this? stackoverflow.com/questions/56802809/…
– DaviesTobi alexJun 28, 2019 at 7:49
-
Is there support for parsing
spring-graphql
annotations and not use leangen annotations?– AlikElzin-kilakaAug 24, 2022 at 12:29
-
@AlikElzin-kilaka The problem is that Spring's GraphQL annotations simply don't fit. They're meant to map methods to an existing schema, and as such don't let you provide enough info to generate the schema. But I'll look into what's possible. SPQR has some support for Microprofile annotations, which are intended to works exactly like the leagnen ones, but are standardized. Unfortunately the support is incomplete at this moment, but it is on my radar.
– kaqqao1 hour ago
After some days’ investigation. I found it is hard to generate schema dynamically in Java (or cost is so high).
Well, from another way. I think we can use Map
as a compromised way to accomplish that.
-
POJO/Entity
public class POJO{ @GraphQLField private Long id; @GraphQLField private String name; // ... @GraphQLField private GMap exts; }
GMap is a customized Map (Because Map/HashMap is a JDK inner class which could not make as GraphQL Schema but only extend).
-
GMap
public class GMap extends HashMap<String, String> { @GraphQLField public String get(@GraphQLName("key") String key) { return super.get(key); } }
-
Retrieve data from Client
// query script query test { your_method { id name exts { get(key: "ext") // Add a extended attribute someday } } } // result { "errors":[], "data": { "list": [ {"id":1, name: "name1", exts: {"get": "ext1"}}, {"id":2, name: "name2", exts: {"get": "ext2"}} ] } }