加入我们,于10月8至10日参加纽约市的活动,了解有关GraphQL联邦和API平台工程的最新技巧、趋势和新闻。加入我们在纽约市的2024年GraphQL峰会
文档
免费开始

Apollo Kotlin中的自定义标量类型


除了它的内建标量类型Int, String等),支持定义 支持 自定义标量。例如,您的架构可能为 定义一个自定义标量,例如为 LongDateBigDecimalGeoPoint

定义类映射

为了与您的 应用中的自定义 进行交互,您需要在您的 build.gradle[.kts] 文件中定义一组映射。这会告诉 Apollo Kotlin 如何表示您的架构中每个自定义 标量

build.gradle[.kts]
apollo {
service("service") {
mapScalar("GeoPoint", "com.example.GeoPoint")
// Shortcuts exist for standard types - equivalent to mapScalar("Long", "kotlin.Long")
mapScalarToKotlinLong("Long")
}
}

如果需要,您也可以使用内置的 标量(如 ID)来重写其默认类型。

定义类适配器

您用来表示自定义 标量 的每个类还需要一个 适配器 来将其转换为和从通过网络发送的 JSON 格式。

每个适配器需要一个 fromJson 函数。如果您的应用将自定义标量作为 传递,则需要一个 toJson 函数。

这里是一个 GeoPoint 自定义 标量 的适配器:

class GeoPoint(val latitude: Double, val longitude: Double)
val geoPointAdapter = object : Adapter<GeoPoint> {
override fun fromJson(reader: JsonReader, customScalarAdapters: CustomScalarAdapters): GeoPoint {
var latitude: Double? = null
var longitude: Double? = null
reader.beginObject()
while(reader.hasNext()) {
when (reader.nextName()) {
"latitude" -> latitude = reader.nextDouble()
"longitude" -> longitude = reader.nextDouble()
}
}
reader.endObject()
// fromJson can throw on unexpected data and the exception will be wrapped in a
// ApolloParseException
return GeoPoint(latitude!!, longitude!!)
}
// If you do not expect your scalar to be used as input, you can leave this method as TODO()
override fun toJson(writer: JsonWriter, customScalarAdapters: CustomScalarAdapters, value: GeoPoint) {
writer.beginObject()
writer.name("latitude").value(value.latitude)
writer.name("longitude").value(value.longitude)
writer.endObject()
}
}

如果您更喜欢使用 Map,Apollo Kotlin 还提供了 AnyAdapter,它支持将 StringIntDoubleBooleanList,和 Map 进行适配。您可以在中间步骤中使用它:

val geoPointAdapter = object : Adapter<GeoPoint> {
override fun fromJson(reader: JsonReader, customScalarAdapters: CustomScalarAdapters): GeoPoint {
val map = AnyAdapter.fromJson(reader) as Map<String, Double>
return GeoPoint(map["latitude"] as Double, map["longitude"] as Double)
}
override fun toJson(writer: JsonWriter, customScalarAdapters: CustomScalarAdapters, value: GeoPoint) {
val map = mapOf(
"latitude" to value.latitude,
"longitude" to value.longitude
)
AnyAdapter.toJson(writer, map)
}
}

此方案更简洁,但性能稍逊一筹。

注册适配器

您定义了适配器后,需要将它们注册。这可以在 build.gradle[.kts] 文件中完成,或者在运行时完成。

build.gradle[.kts]

可以向 mapScalar 函数传递第三个参数来指定要使用的适配器:

build.gradle[.kts]
apollo {
service("service") {
mapScalar("GeoPoint", "com.example.GeoPoint", "com.example.Adapters.geoPointAdapter")
}
}

生成的代码会直接复制给定的表达式。因此,可以传递以下任何一种:

  • 一个实例化表达式,例如 "com.example.GeoPointAdapter()"
  • 一个单例引用,例如 "com.example.GeoPointAdapter"
  • 一个函数调用,例如 "com.example.Adapters.getGeoPointAdapter()"

确保传递包含包名的完整类名,因为不会自动生成导入。

在运行时

还可以通过调用 ApolloClient.Builder.addCustomScalarAdapter 为每个适配器一次性在你的 ApolloClient 实例上注册适配器:

val apolloClient = ApolloClient.Builder().serverUrl("https://example.com/graphql")
.addCustomScalarAdapter(GeoPoint.type, geoPointAdapter)
.build()

此方法接受来自 Types 的类型安全生成类及其对应的适配器。

如果您找不到 Types,请构建项目以触发代码生成。

内置适配器

apollo-api提供了以下内置适配器:

适配器描述
com.apollographql.apollo.api.StringAdapterkotlin.String/java.lang.String 转换为/from
com.apollographql.apollo.api.IntAdapterkotlin.Int/java.lang.Int 转换为/from
com.apollographql.apollo.api.BooleanAdapterkotlin.Boolean/java.lang.Boolean 转换为/from
com.apollographql.apollo.api.DoubleAdapterkotlin.Double/java.lang.Double 转换为/from
com.apollographql.apollo.api.FloatAdapterkotlin.Float/java.lang.Float 转换为/from
com.apollographql.apollo.api.LongAdapterkotlin.Long/java.lang.Long 转换为/from
com.apollographql.apollo.api.AnyAdapterkotlin.Any/java.lang.Object 转换为/from

附加适配器

日期和大数的附加适配器可在以下地址找到:https://github.com/apollographql/apollo-kotlin-adapters

上一页
错误处理
下一页
片段
评价这篇文章评价在GitHub上编辑编辑论坛Discord

©2024阿波罗图形公司,阿波罗GraphQL业务部门。

隐私政策

公司