【问题标题】:GraphQL Java custom scalar type for map is not accepted by schemaSchema 不接受地图的 GraphQL Java 自定义标量类型
【发布时间】:2018-10-24 00:39:08
【问题描述】:

我尝试为 GraphQL Java 添加自定义标量类型。我需要它来解析 Map 而无需为其创建类型,因为它是我的逻辑中常见的返回类型。

我按照说明(这里http://graphql-java.readthedocs.io/en/latest/scalars.html)创建了一个标量类型。

这是我的MapScalar.java

public class MapScalar {
  private static final Logger LOG = LoggerFactory.getLogger(MapScalar.class);

  public static final GraphQLScalarType MAP = new GraphQLScalarType("Map", "A custom map scalar type", new Coercing() {
    @Override
    public Object serialize(Object dataFetcherResult) throws CoercingSerializeException {
      Map map = null;
      try {
        map = Map.class.cast(dataFetcherResult);
      } catch (ClassCastException exception) {
        throw new CoercingSerializeException("Could not convert " + dataFetcherResult + " into a Map", exception);
      }
      return map;
    }

    @Override
    public Object parseValue(Object input) throws CoercingParseValueException {
      LOG.warn("parseValue called");
      return null;
    }

    @Override
    public Object parseLiteral(Object input) throws CoercingParseLiteralException {
      LOG.warn("parseLiteral called");
      return null;
    }
  });
}

我将此标量实例添加到RunTimeWiring

final RuntimeWiring runtimeWiring = newRuntimeWiring()
        .type(queryTypeFactory.getQueryBaseQueryType()) // just convenience methods I made
        .type(queryTypeFactory.getPageQueryType(viewName)) // ...
        .type(queryTypeFactory.getContentQueryType(viewName)) // ...
        .type(queryTypeFactory.getPictureQueryType()) // ...
        .type(queryTypeFactory.getSettingQueryType()) // just convenience methods I made
        .scalar(MapScalar.MAP) // added new scalar here
        .build();

我定义了这个MapDataFetcher

@Component
public class MapDataFetcher implements DataFetcher {

  @Override
  public Object get(DataFetchingEnvironment environment) {
    String fieldName = environment.getField().getName();
    Content source = Content.class.cast(environment.getSource());
    return source.getStruct(fieldName).toNestedMaps(); // returns a Map<String,Object>
  }

}

该字段/标量的架构定义如下:

type Content {
    //... other fields
    settings: Map
}

在调试RunTimeWiring 时,一切似乎都很好。标量已添加到默认标量中:

仍然出现这个错误

SCHWERWIEGEND: Servlet.service() for servlet [cae] in context with path [/blueprint] threw exception [Request processing failed; nested exception is SchemaProblem{errors=[The field type 'Map' is not present when resolving type 'Content' [@10:1], The field type 'Map' is not present when resolving type 'Setting' [@28:1]]}] with root cause
SchemaProblem{errors=[The field type 'Map' is not present when resolving type 'Content' [@10:1], The field type 'Map' is not present when resolving type 'Setting' [@28:1]]}

我在教程中找不到任何后遗症来找出我错过了什么以使其工作。我知道这里缺少类型。但是用newRunTimeWiring().type() 创建一个新类型是用于创建非标量类型,不是吗?还是我还需要在那里创建一个Map 类型?

【问题讨论】:

  • 你的实现很糟糕,如果直接用作输入或变量,这个标量将被默默地忽略。查看更完整的实现here。另外,为什么是时髦的Map.class.cast(dataFetcherResult)?简单的(Map) dataFetcherResult 有什么问题?
  • 我可以更好地阅读它,并提醒我在有 Java Streams API 和方法引用时使用它stream().map(Map.class::cast)

标签: java graphql graphql-java


【解决方案1】:

在教程中没有人提到只有一件小事。 我必须添加这个,所以 Map 实际上被识别为 scala 类型

添加到架构定义文件:

scalar Map

【讨论】:

猜你喜欢
  • 2019-10-12
  • 1970-01-01
  • 2019-06-24
  • 2018-02-12
  • 2021-03-04
  • 1970-01-01
  • 2019-11-15
  • 2015-11-04
相关资源
最近更新 更多