GraphQL中JSON标量的@Argument对应正确输入参数类型是什么
GraphQL自定义JSON标量@Argument注解的正确入参类型
问题根因
使用Map类型接收JSON标量入参时拿到全量请求参数,是Spring for GraphQL参数解析的逻辑特性导致:当@Argument未显式指定绑定的参数名,且接收类型为泛型Map时,框架会默认注入整个GraphQL请求的全量参数集合,而非当前标注字段对应的单独入参。如果Kotlin编译时未开启参数名保留,该问题会100%触发。
正确接收方案
- 优先使用JSON序列化节点类作为接收类型:如果依赖
graphql-java-extended-scalars实现自定义JSON标量,推荐用Jackson的ObjectNode/JsonNode作为接收类型,兼容性最好,支持嵌套结构、数组、布尔、数字等所有JSON合法值,不会出现类型转换错误。 - 若需使用Map接收:必须显式为
@Argument指定绑定的参数名,或者开启编译期参数名保留,避免框架误注入全量参数。注意如果JSON值存在非字符串内容,不要用Map<String, String>,要使用Map<String, Any>声明。
修正后的代码示例
方案1:使用ObjectNode接收(推荐)
@MutationMapping fun addProduct( @Argument("name") name: ObjectNode, @Argument price: BigDecimal, @Argument("description") description: ObjectNode ): Mono<Product>
方案2:使用Map接收
@MutationMapping fun addProduct( @Argument("name") name: Map<String, Any>, @Argument price: BigDecimal, @Argument("description") description: Map<String, Any> ): Mono<Product>
可选配置:免写@Argument显式参数名
在构建配置中开启Kotlin参数名保留编译选项,开启后框架可直接识别方法参数名完成绑定,无需在@Argument中手动传参名。Gradle配置示例:
tasks.withType<KotlinCompile> { kotlinOptions { freeCompilerArgs = listOf("-java-parameters") } }
注意:不建议直接使用
Object作为顶级接收类型,后续取值时需要做多次类型强转,代码可维护性差。
内容的提问来源于stack exchange,提问作者Mykyta Frolov
相关产品推荐
相关产品推荐

