Tapir 文档声明它支持解码密封特征:https ://tapir.softwaremill.com/en/latest/endpoint/customtypes.html#sealed-traits-coproducts
但是,当我尝试使用此代码执行此操作时,出现以下错误:
import io.circe.generic.auto._
import sttp.client3._
import sttp.tapir.{Schema, _}
import sttp.tapir.client.sttp._
import sttp.tapir.generic.auto._
import sttp.tapir.json.circe._
object TmpApp extends App {
sealed trait Result {
def status: String
}
final case class IpInfo(
query: String,
country: String,
regionName: String,
city: String,
lat: Float,
lon: Float,
isp: String,
org: String,
as: String,
asname: String
) extends Result {
def status: String = "success"
}
final case class Fail(message: String, query: String) extends Result {
def status: String = "fail"
}
val sIpInfo = Schema.derive[IpInfo]
val sFail = Schema.derive[Fail]
implicit val sResult: Schema[Result] =
Schema.oneOfUsingField[Result, String](_.status, _.toString)("success" -> sIpInfo, "fail" -> sFail)
val apiEndpoint = endpoint.get
.in("batch")
.in(query[String]("fields"))
.in(jsonBody[List[String]])
.out(jsonBody[List[Result]])
.errorOut(stringBody)
val backend: SttpBackend[Identity, Any] = HttpURLConnectionBackend()
apiEndpoint
.toSttpRequestUnsafe(uri"http://ip-api.com/")
.apply(("4255449", List(
"127.0.0.1"
)))
.send(backend)
.body
}
Exception in thread "main" java.lang.IllegalArgumentException: Cannot decode from [{"status":"fail","message":"reserved range","query":"127.0.0.1"}] of request GET http://ip-api.com//batch?fields=4255449
at sttp.tapir.client.sttp.EndpointToSttpClient.$anonfun$toSttpRequest$7(EndpointToSttpClient.scala:42)
at sttp.client3.ResponseAs.$anonfun$map$1(ResponseAs.scala:27)
at sttp.client3.MappedResponseAs.$anonfun$mapWithMetadata$1(ResponseAs.scala:89)
at sttp.client3.MappedResponseAs.$anonfun$mapWithMetadata$1(ResponseAs.scala:89)
at sttp.client3.internal.BodyFromResponseAs.$anonfun$doApply$2(BodyFromResponseAs.scala:23)
at sttp.client3.monad.IdMonad$.map(IdMonad.scala:8)
at sttp.monad.syntax$MonadErrorOps.map(MonadError.scala:42)
at sttp.client3.internal.BodyFromResponseAs.doApply(BodyFromResponseAs.scala:23)
at sttp.client3.internal.BodyFromResponseAs.$anonfun$apply$1(BodyFromResponseAs.scala:13)
at sttp.monad.syntax$MonadErrorOps.map(MonadError.scala:42)
at sttp.client3.internal.BodyFromResponseAs.apply(BodyFromResponseAs.scala:13)
at sttp.client3.HttpURLConnectionBackend.readResponse(HttpURLConnectionBackend.scala:243)
at sttp.client3.HttpURLConnectionBackend.$anonfun$send$1(HttpURLConnectionBackend.scala:57)
at scala.util.Try$.apply(Try.scala:210)
at sttp.monad.MonadError.handleError(MonadError.scala:14)
at sttp.monad.MonadError.handleError$(MonadError.scala:13)
at sttp.client3.monad.IdMonad$.handleError(IdMonad.scala:6)
at sttp.client3.SttpClientException$.adjustExceptions(SttpClientException.scala:56)
at sttp.client3.HttpURLConnectionBackend.adjustExceptions(HttpURLConnectionBackend.scala:293)
at sttp.client3.HttpURLConnectionBackend.send(HttpURLConnectionBackend.scala:31)
at sttp.client3.HttpURLConnectionBackend.send(HttpURLConnectionBackend.scala:23)
at sttp.client3.FollowRedirectsBackend.sendWithCounter(FollowRedirectsBackend.scala:22)
at sttp.client3.FollowRedirectsBackend.send(FollowRedirectsBackend.scala:17)
at sttp.client3.RequestT.send(RequestT.scala:299)
at onlinenslookup.ipapi.TmpApp$.delayedEndpoint$onlinenslookup$ipapi$TmpApp$1(TmpApp.scala:53)
at onlinenslookup.ipapi.TmpApp$delayedInit$body.apply(TmpApp.scala:11)
at scala.Function0.apply$mcV$sp(Function0.scala:39)
at scala.Function0.apply$mcV$sp$(Function0.scala:39)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:17)
at scala.App.$anonfun$main$1(App.scala:73)
at scala.App.$anonfun$main$1$adapted(App.scala:73)
at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:553)
at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:551)
at scala.collection.AbstractIterable.foreach(Iterable.scala:920)
at scala.App.main(App.scala:73)
at scala.App.main$(App.scala:71)
at onlinenslookup.ipapi.TmpApp$.main(TmpApp.scala:11)
at onlinenslookup.ipapi.TmpApp.main(TmpApp.scala)
Caused by: DecodingFailure(CNil, List(DownArray))
Process finished with exit code 1
构建.sbt:
"com.softwaremill.sttp.tapir" %% "tapir-core" % "0.17.0-M10",
"com.softwaremill.sttp.tapir" %% "tapir-sttp-client" % "0.17.0-M10",
"com.softwaremill.sttp.tapir" %% "tapir-json-circe" % "0.17.0-M10",
可以在此处找到此特定端点的文档:https ://ip-api.com/docs/api:batch