在 graphql-java 中注册自定义标量

Posted

技术标签:

【中文标题】在 graphql-java 中注册自定义标量【英文标题】:Registering Custom Scalar in graphql-java 【发布时间】:2020-08-03 23:37:06 【问题描述】:

我按照这里的文档https://www.graphql-java.com/documentation/v14/scalars/ 但遇到以下错误: SchemaProblemerrors=[解析类型“Book”时字段类型“Date”不存在[@5:1]]

schema.graphqls

type Query 
    bookById(id: ID!): Book


type Book 
    id: ID
    name: String
    date: Date


使用 graphql-java 14.0

    private static GraphQLScalarType DATE_SCALAR = GraphQLScalarType.newScalar().name("Date").coercing(new Coercing<LocalDate, LocalDate>() 
        @Override
        public LocalDate serialize(Object input) 
            return input == null ? null : LocalDate.parse(input.toString());
        

        @Override
        public LocalDate parseValue(Object input) 
            return input == null ? null : LocalDate.parse(input.toString());
        

        @Override
        public LocalDate parseLiteral(Object input) 
            if (input instanceof StringValue) 
                try 
                    return LocalDate.parse(((StringValue) input).getValue());
                 catch (DateTimeParseException e) 
                    throw new CoercingParseLiteralException(e);
                
            

            throw new CoercingParseLiteralException();
        
    ).build();

    public static GraphQL graphQL() 
        SchemaParser schemaParser = new SchemaParser();

        TypeDefinitionRegistry typeRegistry;

        try (InputStream is = MainApplication.class.getClassLoader().getResourceAsStream("schema.graphqls");
                Reader reader = new InputStreamReader(is, "utf-8")) 
            typeRegistry = schemaParser.parse(reader);

         catch (IOException e) 
            throw new UncheckedIOException(e);
        

        SchemaGenerator schemaGenerator = new SchemaGenerator();
        GraphQLSchema schema = schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring());

        return GraphQL.newGraphQL(schema).build();
    

    private static RuntimeWiring runtimeWiring() 
        Builder builder = RuntimeWiring.newRuntimeWiring();
        builder.scalar(DATE_SCALAR);

        builder.type("Query", typeWiring -> 
            typeWiring.dataFetcher("bookById", environment -> Map.of("name", "GraphQL"));
            return typeWiring;
        );
        return builder.build();
    

    public static void main(String[] args) throws InterruptedException, ExecutionException 
        GraphQL graphQL = graphQL();

        ExecutionInput.Builder executionInputBuilder = ExecutionInput.newExecutionInput().query(" bookById(id: 1)  name  ");
        executionInputBuilder.dataLoaderRegistry(new DataLoaderRegistry());
        ExecutionInput executionInput = executionInputBuilder.build();

        Map<String, Object> result = CompletableFuture.completedFuture(executionInput).thenCompose(graphQL::executeAsync).thenApply(ExecutionResult::toSpecification).get();
        System.out.println(result);
    

【问题讨论】:

我需要将 ScalarTypeDefinition 添加到 TypeDefinitionRegistry 以使其工作。 【参考方案1】:

标量日期

在 schema.graphqls 中遗漏了。

添加之后,自定义标量就起作用了。

【讨论】:

以上是关于在 graphql-java 中注册自定义标量的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL使用之graphql-java自定义标量类型

graphql-java:如何在以编程方式生成 graphql 模式时添加自定义标量类型?

Flink Table API & SQL 自定义 Scalar 标量函数

为啥 Azure 将不同的 HTML 嵌入到自定义和内置策略的自定义 UI 注册表单中?

SqlServer如何用Sql语句自定义聚合函数

AD B2C 自定义策略自定义声明出现错误“无法验证提供的信息”。注册时