首页 > 解决方案 > 如何在 GraphQL SPQR 中将子类视为其父类

问题描述

我围绕 BigDecimal 创建了一个包装器。基本上只是在上面放了一堆更友好的方法。我将它用于我的一些 POJO 字段,它会生成这样的模式

# Built-in java.math.BigDecimal
scalar BigDecimal

input BestDecimalInput {
  scale: Int!
}

理想情况下,当我进行查询时,我可以将其视为 BigDecimal。我有一个构造函数

public BestDecimal(double val) {
        super(val);
    }

我希望它可以让我在查询/突变中使用常规浮点数,但它似乎并没有那样工作。基本上,如果下面是一个 BestDecimal 对象,我希望它像 BigDecimal 一样工作。

myquery(number: 10){
  whatever
}

标签: javagraphqlgraphql-spqrgraphql-spqr-spring-boot-starter

解决方案


你可以做两件事。

  • 将您的类映射为自定义标量。为此,您必须实现自定义TypeMapper并将其连接。

  • 或者,您可以提供TypeAdapter适应的自定义,BestDecimal反之亦然BigDecimal

查看TypeMapperor的现有实现TypeAdapter,例如OptionalIntAdapter(使OptionalInt充当Integer),并在此基础上创建一个新实现。或查看此答案以获取自定义标量。

您可以使用generator.withTypeMappers或连接它generator.withTypeAdapters

使用 Spring Starter,您可以添加TypeMapper如下内容:

@Bean
public ExtensionProvider<GeneratorConfiguration, TypeMapper> mappers() {
    //After IdAdapter is generally a safe place to insert custom mappers
    return (config, mappers) -> mappers.insertAfter(IdAdapter.class, new YouCustomMapper());
}

TypeAdapter不幸的是,您不能直接接线。您必须将它连接为TypeMapper,InputConverter同时OutputConverter,这很烦人。所以相反,添加一个自定义模块会更容易TypeAdapter

@Bean
public ExtensionProvider<GeneratorConfiguration, Module> modules() {
    return (config, modules) -> modules.append(context -> 
         context.getSchemaGenerator().withTypeAdapters(new YourCustomAdapter()));
}

您当然可以(并且应该)开设一个合适的Module班级,而不是像我一样开设一个匿名班级。


推荐阅读