模式不接受地图的 GraphQL Java 自定义标量类型
GraphQL Java custom scalar type for map is not accepted by schema
我尝试为 GraphQL 添加自定义标量类型 Java。我需要它来解析 Map 而无需为其创建类型,因为它是我逻辑中的常见 return 类型。
我按照说明(此处: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>
}
}
此 field/scalar 的架构定义如下:
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
类型吗?
只有一件小事遗漏了教程中没有提到的。
我必须添加这个所以 Map
实际上被识别为一个 scala 类型
添加到架构定义文件:
scalar Map
我尝试为 GraphQL 添加自定义标量类型 Java。我需要它来解析 Map 而无需为其创建类型,因为它是我逻辑中的常见 return 类型。
我按照说明(此处: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>
}
}
此 field/scalar 的架构定义如下:
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
类型吗?
只有一件小事遗漏了教程中没有提到的。
我必须添加这个所以 Map
实际上被识别为一个 scala 类型
添加到架构定义文件:
scalar Map