GraphQL(四)自定义标量[Scalar]详解

简介: 本文介绍GraphQL的标量拓展、自定义标量的定义及使用。从版本 3.9.2 开始,DGS 框架具有graphql-dgs-extended-scalars模块。此模块提供自动配置,将自动注册库中定义的标量扩展 `com.graphql-java:graphql-java-extended-scalars`。

GraphQL默认标量类型

  • Int:有符号 32 位整数。
  • Float:有符号双精度浮点值。
  • String:UTF‐8 字符序列。
  • Boolean:true 或者 false。
  • ID:ID 标量类型表示一个唯一标识符

GraphQL默认标量类型详见对象类型和字段

除了以上GraphQL 规范定义的内置标量,使用其他类型如Long/BigDecimal/Date等,需要自定标量

标量拓展

从版本 3.9.2 开始,DGS 框架具有graphql-dgs-extended-scalars模块。此模块提供自动配置,将自动注册库中定义的标量扩展 com.graphql-java:graphql-java-extended-scalars

使用标量拓展的步骤:

  1. 使用maven/gradle添加com.netflix.graphql.dgs:graphql-dgs-extended-scalars依赖
<dependency>
    <groupId>com.netflix.graphql.dgs</groupId>
    <artifactId>graphql-dgs-extended-scalars</artifactId>
    <version>${dgs.version}</version>
</dependency>
  1. Schema配置标量
scalar Date
  1. 启动注册
dgs:
  graphql:
    extensions:
      scalars:
        time-dates:
          enabled: true

拓展标量开关

graphql-java-extended-scalars模块提供了一些可用于关闭注册的开关

参数 描述
dgs.graphql.extensions.scalars.time-dates.enabled 如果设置为false,它将不会注册 DateTime、Date 和 Time 标量扩展
dgs.graphql.extensions.scalars.objects.enabled 如果设置为false,它将不会注册 Object、Json、Url 和 Locale 标量扩展
dgs.graphql.extensions.scalars.numbers.enabled 如果设置为false,则不会注册所有数字标量扩展,例如 PositiveInt、NegativeInt 等
dgs.graphql.extensions.scalars.chars.enabled 如果设置为false,则不会注册 GraphQLChar 扩展
dgs.graphql.extensions.scalars.enabled 如果设置为false,它将禁用上述所有内容的自动注册

拓展标量

graphql-java-extended-scalars添加了以下在基于 Java 的系统中很有用的标量类型:

  • Long aka GraphQLLong - 基于 java.lang.Long 的标量
  • Short aka GraphQLShort - 基于 java.lang.Short 的标量
  • Byte aka GraphQLByte - 基于 java.lang.Byte 的标量
  • BigDecimal aka GraphQLBigDecimal - 基于 java.math.BigDecimal 的标量
  • BigInteger aka GraphQLBigInteger - 基于 java.math.BigInteger 的标量

更多拓展标量,如URLJSON等可见graphql-java

自定义标量

任何自定义标量需要实现graphql.schema.Coercing接口。包括以下 3 个功能:

  • parseValue:将查询变量中的输入解析为可接受标量类型的 Java 对象
  • parseLiteral:在查询验证期间被调用,将查询输入 AST 节点转换为可接受标量类型的 Java 对象。输入对象将是graphql.language.Value的实例
  • serialize:将 DataFetcher 返回的 Java 对象转换为标量类型的有效运行时对象

自定义标量实例

创建一个实现graphql.schema.Coercing接口的类并用@DgsScalar注解对其进行注解。还要确保在 GraphQL schema 中定义了标量类型

一个简单的LocalDateTime实现

@DgsScalar(name="DateTime")
public class DateTimeScalar implements Coercing<LocalDateTime, String> {
   
    @Override
    public String serialize(Object dataFetcherResult) throws CoercingSerializeException {
   
        if (dataFetcherResult instanceof LocalDateTime) {
   
            return ((LocalDateTime) dataFetcherResult).format(DateTimeFormatter.ISO_DATE_TIME);
        } else {
   
            throw new CoercingSerializeException("Not a valid DateTime");
        }
    }

    @Override
    public LocalDateTime parseValue(Object input) throws CoercingParseValueException {
   
        return LocalDateTime.parse(input.toString(), DateTimeFormatter.ISO_DATE_TIME);
    }

    @Override
    public LocalDateTime parseLiteral(Object input) throws CoercingParseLiteralException {
   
        if (input instanceof StringValue) {
   
            return LocalDateTime.parse(((StringValue) input).getValue(), DateTimeFormatter.ISO_DATE_TIME);
        }

        throw new CoercingParseLiteralException("Value is not a valid ISO date time");
    }
}

Schema

scalar DateTime

详细例子可见Writing your own Custom Scalars


参考资料:

  1. GraphQL(一)基础介绍及应用示例
  2. Adding Custom Scalars
  3. graphql-dgs-extended-scalars
相关文章
|
存储 XML Java
Flowable工作流-高级篇
Flowable工作流-高级篇
7837 1
|
Java 开发者
GraphQL(五)指令[Directive]详解
本文介绍GraphQL的指令Directive详解,包括基础指令和可拓展指令;并在文章最后记录了两种方式的参数校验指令例子。对于请求参数的校验,推荐使用方式,而可适用于各种DSL元素的校验。
|
小程序
支付宝扫码跳转小程序并传参
支付宝扫码跳转小程序并传参
2147 1
|
存储 NoSQL 关系型数据库
Redis(六)set集合类型
set集合和list列表十分的相似,都可以存储多个字符串。但是list列表可以存储重复值,而set集合中不可重复。
7586 0
Redis(六)set集合类型
|
应用服务中间件 nginx Docker
使用nginx进行http以及socket端口转发(快速提高docker开发效率)
本文介绍如何使用nginx进行http以及socket端口转发以快速提高docker开发效率
|
6月前
|
人工智能 安全 API
2025电商API新特性:实时数据流、GraphQL接口与隐私合规
2025年电商API迎来技术与合规双重革新,实时数据流、GraphQL接口、隐私合规成为核心突破方向,推动全息电商、动态定价、供应链协同等场景升级,实现性能优化与用户隐私保护的协同发展。
|
缓存 安全 Java
Spring Boot与GraphQL的集成最佳实践
Spring Boot与GraphQL的集成最佳实践
|
12月前
|
算法 安全 Java
Java线程调度揭秘:从算法到策略,让你面试稳赢!
在社招面试中,关于线程调度和同步的相关问题常常让人感到棘手。今天,我们将深入解析Java中的线程调度算法、调度策略,探讨线程调度器、时间分片的工作原理,并带你了解常见的线程同步方法。让我们一起破解这些面试难题,提升你的Java并发编程技能!
467 16
|
JSON 小程序 前端开发
vant weapp 在小程序中的使用
vant weapp 在小程序中的使用
533 1
|
Java Maven 编译器
Java编译器注解运行和自动生成代码问题之Maven编译时设置生成的源码的文件夹路径问题如何解决
Java编译器注解运行和自动生成代码问题之Maven编译时设置生成的源码的文件夹路径问题如何解决
360 0