动态生成 GraphQL 模式支持

Posted

技术标签:

【中文标题】动态生成 GraphQL 模式支持【英文标题】:Dynamic generate GraphQL schema supports 【发布时间】:2017-06-24 03:32:21 【问题描述】:

是否可以动态创建 GraphQL 架构?

我们将数据存储在 mongoDB 中,并且有可能添加新字段。我们不希望 mongoDB 文档中这个新添加的字段发生任何代码更改。

有什么方法可以动态生成模式?

Schema 是在代码中定义的,但是对于 java(schema as pojo),当 new 添加属性,您必须更新并重新编译代码,然后 再次归档并部署 jar。任何生成模式的方法 数据而不是预先定义它?

目前我们正在使用 java 相关项目(graphql-java、graphql-java-annotations)进行 GraphQL 开发。

【问题讨论】:

【参考方案1】:

您可以使用graphql-spqr,它允许您根据服务类自动生成架构。在你的情况下,它看起来像这样:

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;

大概,您有​​一个包含业务逻辑的服务类:

public class PojoService 

    //this could also return List<Pojo> or whatever is applicable
    @GraphQLQuery(name = "pojo")
    public Pojo getPojo() ...

要公开此服务,您只需执行以下操作:

GraphQLSchema schema = new GraphQLSchemaGenerator()
                .withOperationsFromSingleton(new PojoService())
                .generate();

然后您可以触发如下查询:

query test 
    pojo 
        id
        name 
        exts 
            something
            somethingElse
          

不需要奇怪的包装器或任何类型的自定义代码,也不需要牺牲类型安全。适用于泛型、依赖注入或您项目中可能拥有的任何其他爵士乐。

全面披露:我是graphql-spqr的作者。

【讨论】:

拜托,你能帮忙吗? ***.com/questions/56802809/…【参考方案2】:

经过几天的调查。我发现很难在 Java 中动态生成模式(或者成本太高)。

嗯,从另一种方式。我认为我们可以使用Map 作为一种折衷的方式来实现这一目标。

POJO/实体

public class POJO
    @GraphQLField
    private Long id;

    @GraphQLField
    private String name;

    // ...

    @GraphQLField
    private GMap exts;   

GMap 是一个自定义的 Map(因为 Map/HashMap 是一个 JDK 内部类,它不能作为 GraphQL Schema,只能扩展)。

地图

public class GMap extends HashMap<String, String> 

    @GraphQLField
    public String get(@GraphQLName("key") String key) 
        return super.get(key);
    

从客户端检索数据

// 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"
        ]
    

【讨论】:

以上是关于动态生成 GraphQL 模式支持的主要内容,如果未能解决你的问题,请参考以下文章

生成动态 GraphQL Schema

动态代理与反射在GraphQL客户端的应用

为中继自动生成 graphql 模式(石墨烯服务器)

如何根据模式动态生成数据集?

如何使用 Apollo 在 Nuxt 生成的动态页面中正确填充页眉?

多个基表不支持动态 sql 生成