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

如何为作为GraphQL参数的类设置全局默认值?

问题描述

我不确定“全局默认值”是不是最佳表述,或许叫“默认的默认值”更合适?不管怎样,问题如下:
针对返回集合的GraphQL查询,我定义了如下PagingOptions类:

public class PagingOptions {
   public int start = 0;
   public int limit = 100;
   public SortOptions sort = null;
}

示例查询方法为:

public Page<UserType> getUsers(@GraphQLArgument StandardCollectionArgs options)

PagingOptions字段的默认值已经在类声明里定义了,怎么把它设为查询中options参数的默认值?我可以用@GraphQLArgument(defaultValue="PagingOptions的JSON表示"),但每个用到该参数的地方都得重复配置,defaultValueProvider也是如此。有没有办法把默认值和作为GraphQLArgument的类关联起来?

可行解决方案

1. 自定义参数解析器(推荐)

实现GraphQL的参数解析逻辑,让所有PagingOptions类型的参数自动使用类的默认实例,不用逐个方法配置。

拿Spring GraphQL举例,自定义ArgumentValueResolver:

@Component
public class PagingOptionsArgumentResolver implements ArgumentValueResolver {

    @Override
    public boolean supports(Argument argument) {
        return PagingOptions.class.isAssignableFrom(argument.getType().getJavaType());
    }

    @Override
    public Object resolve(Argument argument, ValueFetchingEnvironment environment) {
        // 请求没传参数时,返回默认实例
        Object providedValue = environment.getArgumentValue();
        if (providedValue == null) {
            return new PagingOptions();
        }
        // 传了部分参数的话,用默认值补全(可以用BeanUtils或MapStruct做属性拷贝)
        PagingOptions defaultOptions = new PagingOptions();
        BeanUtils.copyProperties(providedValue, defaultOptions);
        return defaultOptions;
    }
}

配置后,所有用到PagingOptions作为GraphQL参数的地方,都会自动套用类里的默认值,无需重复写配置。

2. 绑定默认值到GraphQL输入类型

直接在GraphQL的输入类型定义里把默认值和字段绑定,不管哪个查询用这个类型,都会继承这些默认值。

如果用SDL(Schema定义语言):

input PagingOptions {
  start: Int = 0
  limit: Int = 100
  sort: SortOptions
}

type Query {
  getUsers(options: PagingOptions = {}): Page<UserType>
}

这里options: PagingOptions = {}会自动触发输入类型的字段默认值,对应到Java类的默认初始化值。

如果是代码优先的方式,直接在定义输入类型时指定默认值:

@Bean
public GraphQLInputType pagingOptionsInputType() {
    return GraphQLInputObjectType.newInputObject()
            .name("PagingOptions")
            .field(field -> field.name("start").type(GraphQLInt).defaultValue(0))
            .field(field -> field.name("limit").type(GraphQLInt).defaultValue(100))
            .field(field -> field.name("sort").type(sortOptionsInputType()))
            .build();
}

3. 自定义注解+全局处理器

定义一个注解标记需要用默认实例的参数,再写全局处理器自动生成默认实例,扩展性更强,其他类也能复用。

先定义注解:

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseDefaultInstance {
}

修改查询方法,给参数加注解:

public Page<UserType> getUsers(@GraphQLArgument @UseDefaultInstance PagingOptions options)

然后实现全局参数解析器:

@Component
public class DefaultInstanceArgumentProcessor implements ArgumentValueResolver {

    @Override
    public boolean supports(Argument argument) {
        return argument.getAnnotations().stream()
                .anyMatch(anno -> anno.annotationType() == UseDefaultInstance.class);
    }

    @Override
    public Object resolve(Argument argument, ValueFetchingEnvironment environment) {
        try {
            Class<?> paramType = argument.getType().getJavaType();
            return paramType.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("无法创建默认实例", e);
        }
    }
}

这样只要参数加了@UseDefaultInstance,就会自动用类的默认实例当参数默认值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:47:30