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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 06:09:26