问题
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.
回答1:
You could use graphql-spqr, 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.
回答2:
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"}} ] } }
来源:https://stackoverflow.com/questions/42080536/dynamic-generate-graphql-schema-supports