Open1

Kotlinのvalue class

kitwtnbkitwtnb

Kotlinの value class 、kotlinx.serialization、Retrofitの組み合わせでハマった。

たとえば以下のようなinterfaceを定義する。

@Serializable
@JvmInline
value class UserId(val value: Int)

interface Api {
    @GET("/user")
    suspend fun getUser(@Query("id") id: UserId): User
}

value classをkotlinx.serializationでエンコードすると生の値が文字列として取得できた。
なので api.getUser(UserId(1)) という処理を実行すると /user?id=1 にリクエストが送信されることを期待していたが、実際には /user?id=UserId%... のようなUserIdがURLエンコードされた状態で送られていた。

そもそも @Query@Path はJSONで指定しないので、 toString() をoverrideすることで意図したパラメータが設定された。

@Serializable
@JvmInline
value class UserId(val value: Int) {
    override fun toString(): String = value.toString()
}