和我们一起于10月8日至10日在纽约市参加活动,了解关于GraphQL联邦和API平台工程的最新技巧、趋势和新闻。与我们在纽约市参加GraphQL summit 2024
文档
免费开始
您正在查看此软件之前的版本的文档。 切换到最新稳定版本。

Apollo Kotlin 中的自定义标量类型


除了其内置标量类型Int, String 等.), 支持自定义标量。例如,您的模式可能定义了一个用于 Long, Date, BigDecimalGeoPoint 的自定义标量。

定义类映射

在与您的 Apollo Kotlin 应用中的自定义 进行交互时,您需要在您的 build.gradle[.kts] 文件中定义一个映射。这将告诉 Apollo Kotlin 使用哪个类来表示您 schema 中的每个自定义 标量

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 函数。如果您的应用将自定义 标量作为 GraphQL 传递,则需要一个 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,它支持将 StringIntDoubleBooleanListMap 进行适配。您可以在中间步骤中使用它:

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://")
.addCustomScalarAdapter(GeoPoint.type, geoPointAdapter)
.build()

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

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

由 Apollo 提供的适配器

以下内置适配器可以与常见的自定义 标量 类型一起使用:

适配器描述
com.apollographql.apollo3.api.FloatAdapter转换 kotlin.Float/java.lang.Float
com.apollographql.apollo3.api.LongAdapter转换 kotlin.Long/java.lang.Long

除此之外,com.apollographql.apollo3:apollo-adapters 软件包还提供了以下适配器:

适配器描述
com.apollographql.apollo3.adapter.KotlinxInstantAdapter用于 kotlinx.datetime.Instant ISO8601 日期
com.apollographql.apollo3.adapter.JavaInstantAdapter用于 java.time.Instant ISO8601 日期
com.apollographql.apollo3.adapter.KotlinxLocalDateAdapter用于 kotlinx.datetime.LocalDate ISO8601 日期
com.apollographql.apollo3.adapter.JavaLocalDateAdapter用于 java.time.LocalDate ISO8601 日期
com.apollographql.apollo3.adapter.KotlinxLocalDateTimeAdapter用于 kotlinx.datetime.LocalDateTime ISO8601 日期
com.apollographql.apollo3.adapter.JavaLocalDateTimeAdapter用于 java.time.LocalDateTime ISO8601 日期
com.apollographql.apollo3.adapter.KotlinxLocalTimeAdapter用于 kotlinx.datetime.LocalTime ISO8601 日期
com.apollographql.apollo3.adapter.JavaLocalTimeAdapter用于 java.time.LocalTime ISO8601 日期
com.apollographql.apollo3.adapter.JavaOffsetDateTimeAdapter用于 java.time.OffsetDateTime ISO8601 日期
com.apollographql.apollo3.adapter.DateAdapter用于 java.util.Date ISO8601 日期
com.apollographql.apollo3.adapter.BigDecimalAdapter用于包含大数值的 Multiplatform com.apollographql.apollo3.adapter.BigDecimal

注意:由于一些适配器使用了 kotlinx.datetime(它本身又使用了 java.time),您需要在 Android API 级别 < 26 上启用 核心库降级

例如,要使用 DateAdapter,请按照以下方式配置您的 Gradle 脚本:

build.gradle[.kts]
dependencies {
implementation("com.apollographql.apollo3:apollo-adapters:3.8.5")
}
apollo {
service("service") {
mapScalar("Date", "java.util.Date", "com.apollographql.apollo3.adapter.DateAdapter")
}
}
上一页
错误处理
下一页
片段
评价文章评价

©2024Apollo Graph Inc.,即Apollo GraphQL。

隐私政策

公司