You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GraphQL Schema中指定DateTime类型?

解决GraphQL Schema中日期类型报错的问题

GraphQL本身没有内置DateTime或Date类型,直接使用会触发Unknown type DateTime错误,你需要通过自定义标量类型来处理Java中的LocalDate字段,具体步骤如下:

1. 在GraphQL Schema中声明自定义标量

先在Schema顶部声明对应LocalDate的标量,再在Pet类型中使用:

scalar LocalDate

type Pet {
    id: ID!
    name: String!
    description: String
    birthDate: LocalDate
}

2. 实现标量的序列化与反序列化(自定义实现)

如果不想用第三方库,自己写一个标量处理类,完成LocalDate和字符串(ISO格式yyyy-MM-dd)之间的转换:

import graphql.schema.Coercing;
import graphql.schema.GraphQLScalarType;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

public class LocalDateScalar {
    public static final GraphQLScalarType LOCAL_DATE = GraphQLScalarType.newScalar()
            .name("LocalDate")
            .description("对应Java LocalDate类型,输入输出格式为yyyy-MM-dd")
            .coercing(new Coercing<LocalDate, String>() {
                // 从Java对象序列化为GraphQL响应的字符串
                @Override
                public String serialize(Object input) {
                    if (input instanceof LocalDate) {
                        return ((LocalDate) input).format(DateTimeFormatter.ISO_LOCAL_DATE);
                    }
                    throw new IllegalArgumentException("序列化失败:输入不是LocalDate类型");
                }

                // 从客户端传入的变量解析为LocalDate
                @Override
                public LocalDate parseValue(Object input) {
                    if (input instanceof String) {
                        try {
                            return LocalDate.parse((String) input, DateTimeFormatter.ISO_LOCAL_DATE);
                        } catch (DateTimeParseException e) {
                            throw new IllegalArgumentException("解析失败:日期格式应为yyyy-MM-dd");
                        }
                    }
                    throw new IllegalArgumentException("解析失败:输入不是字符串类型");
                }

                // 从GraphQL查询的字面量解析为LocalDate
                @Override
                public LocalDate parseLiteral(Object input) {
                    if (input instanceof String) {
                        try {
                            return LocalDate.parse((String) input, DateTimeFormatter.ISO_LOCAL_DATE);
                        } catch (DateTimeParseException e) {
                            throw new IllegalArgumentException("解析失败:日期格式应为yyyy-MM-dd");
                        }
                    }
                    throw new IllegalArgumentException("解析失败:字面量不是字符串类型");
                }
            })
            .build();
}

3. 注册自定义标量到GraphQL引擎

以Spring GraphQL为例,通过配置类把标量注册到系统中:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import graphql.schema.GraphQLScalarType;

@Configuration
public class GraphQLConfig {
    @Bean
    public GraphQLScalarType localDateScalar() {
        return LocalDateScalar.LOCAL_DATE;
    }
}

可选:使用现成的扩展标量库

如果不想重复造轮子,可以引入graphql-java-extended-scalars库,它已经封装了LocalDate、LocalDateTime等常用标量:

  1. 引入Maven依赖(版本需匹配你的graphql-java版本):
<dependency>
    <groupId>com.graphql-java</groupId>
    <artifactId>graphql-java-extended-scalars</artifactId>
    <version>21.0</version>
</dependency>
  1. 注册预定义的标量:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import graphql.scalars.ExtendedScalars;

@Configuration
public class GraphQLConfig {
    @Bean
    public GraphQLScalarType localDateScalar() {
        return ExtendedScalars.LocalDate;
    }
}

内容的提问来源于stack exchange,提问作者user15793405

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 20:10:25