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

如何让同类型GraphQL查询返回OrderResult,解决类型不匹配问题?

解决Apollo GraphQL查询类型不匹配问题

核心原因

Apollo默认使用operationBased代码生成模式,每个查询会生成独立的Kotlin数据类——哪怕GraphQL返回的是同一底层类型,也会被拆分成不同的类(比如FindOrderByRestaurantIdQuery.FindOrderByRestaurantId和FindOrderByOidQuery.FindOrderByOid),直接导致类型不兼容。

解决方案

1. 修改Apollo代码生成模式

在Gradle的Apollo配置中,启用responseBased模式,让相同的GraphQL类型生成共用的Kotlin类:

apollo {
    service("myapp") {
        packageName.set("com.myapp.app")
        // 启用responseBased模式,共用GraphQL类型对应的Kotlin类
        codegenModels.set("responseBased")
        introspection {
            endpointUrl.set("https://endpoint.com/data/")
            schemaFile.set(file("src/main/graphql/sg/com/myapp/app/schema.graphqls"))
        }
        customTypeMapping = [
                "Date"    : "kotlin.String",
                "DateTime": "kotlin.String",
                "Time"    : "kotlin.String",
                "BigInt"  : "kotlin.Long",
                "Double"  : "kotlin.Double"
        ]
    }
}

2. 使用GraphQL Fragment复用字段定义

创建Fragment文件(路径示例:src/main/graphql/com/myapp/app/OrderResultFragment.graphql),统一定义OrderResult类型的所有字段:

fragment OrderResultFragment on OrderResult {
  # 列出OrderResult的所有字段,比如:
  id
  oid
  restaurantId
  # ... 其他近百个字段,直接从Schema中复制即可
}

然后在两个查询文件中引用该Fragment,确保返回结果类型统一:
FindOrderByRestaurantIdQuery.graphql:

query FindOrderByRestaurantId($id: String!) {
  findOrderByRestaurantId(id: $id) {
    ...OrderResultFragment
  }
}

FindOrderByOidQuery.graphql:

query FindOrderByOid($oid: String!) {
  findOrderByOid(oid: $oid) {
    ...OrderResultFragment
  }
}

3. 更新Kotlin代码中的集合类型

将orderListData的类型改为Fragment对应的共用类型,调整后的代码如下:

// 统一使用OrderResultFragment类型
var orderListData: ArrayList<OrderResultFragment?> = ArrayList()

fun getOrderList(){
    scope.launch {
        apolloBuilder.apolloBuild().query(
            FindOrderByRestaurantIdQuery(
                id = "1"
            )
        ).execute().apply {
            orderListData = data?.findOrderByRestaurantId?.toCollection(ArrayList()) ?: ArrayList()
        }
    }
}

fun getOrderDetail(){
    scope.launch {
        apolloBuilder.apolloBuild().query(
            FindOrderByOidQuery(
                oid = "15"
            )
        ).execute().apply {
            data?.findOrderByOid?.let {
                orderListData.add(it)
            }
        }
    }
}

4. 清理并重新构建项目

  • 删除旧的生成代码(默认路径:build/generated/source/apollo)
  • 执行./gradlew clean build重新生成代码并构建项目

注意事项

  • 若需兼容旧代码,可改用compatible代码生成模式(codegenModels.set("compatible")),它会同时生成共用类型和旧的操作专属类型
  • 确保Fragment包含的字段与两个查询原本返回的字段完全一致,避免遗漏或冗余

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:55:55