Apollo3.3.2 KMM中如何避免手动包裹Optional.presentIfNotNull
问题原因
generateOptionalOperationVariables配置不生效是作用域不匹配导致的:
- 该配置仅控制Query/Mutation/Subscription顶层操作变量的生成规则
- 你代码中使用的
QueryTrainingsForUserWhereWhereConditions属于GraphQL输入对象(Input Type),其字段生成逻辑由独立配置控制,不受上述开关影响。
Apollo Kotlin 3.x默认对所有可选的输入类型字段使用Optional<T>包装,目的是明确区分「字段未传递」和「字段传递null值」两种语义,这是和v2版本的默认行为差异。
最优解决方案(还原v2写法)
在模块级build.gradle.kts的Apollo配置块中添加针对输入字段的配置,直接取消Optional包装:
apollo { // 其余原有配置保持不变 // 新增以下配置,控制可选输入字段的生成形式 optionalInputFields.set("nullable") }
配置说明:
optionalInputFields支持三个取值:apolloOptional:默认值,即你当前看到的所有可选字段用Optional<T>包裹、默认值为Optional.Absent的形式nullable:所有可选字段直接生成为Kotlin可空类型T?,默认值为null,完全对齐v2版本的传参习惯,无需额外包裹任何内容javaOptional:适配Java用户的java.util.Optional包装,KMM项目无需使用
配置修改完成后执行Gradle的clean任务再重新编译,自动生成的输入类会变成如下结构,可直接传值:
public data class QueryTrainingsForUserWhereWhereConditions( public val column: TrainingColumn? = null, public val `operator`: SQLOperator? = null, public val `value`: Any? = null, public val AND: List<QueryTrainingsForUserWhereWhereConditions>? = null, public val OR: List<QueryTrainingsForUserWhereWhereConditions>? = null, public val HAS: QueryTrainingsForUserWhereWhereConditionsRelation? = null, )
此时就可以直接使用v2时期的写法传参,无需任何Optional相关调用。
轻量替代方案(不修改全局生成规则)
如果因为项目兼容原因不能修改全局生成配置,可以写一个通用顶层扩展函数缩短包装代码的长度:
fun <T> T?.wrap(): Optional<T> = Optional.presentIfNotNull(this)
使用时直接在参数后加.wrap()即可,替代冗长的Optional.presentIfNotNull()调用:
val officeId = QueryTrainingsForUserWhereWhereConditions( TrainingColumn.OFFICE_ID.wrap(), SQLOperator.IS_NULL.wrap() )
额外优化建议
如果经常需要写嵌套的查询条件(比如多层AND/OR/HAS逻辑),可以同时开启输入类的Builder生成:
apollo { optionalInputFields.set("nullable") generateInputBuilders.set(true) }
开启后会为每个输入类型生成DSL风格的Builder,嵌套构造条件时代码可读性会更高。
内容的提问来源于stack exchange,提问作者ALKIN ÇAKIRALAR
相关产品推荐
相关产品推荐

