-
Notifications
You must be signed in to change notification settings - Fork 449
Closed
Milestone
Description
Tapir: 1.0.0-M1
uPickle: 1.5.0
sttp: 3.5.1
Scala version: 2.12.13
Describe the bug
I am working with a JSON document that omits optional values, yet I can't figure out how to use optional fields with tapir
and uPickle
.
I would like to generate a client that can accept all to accept all three example responses for Message
. Currently the commented baseEndpoint
does not compile because Tapir cannot find an implicit value. Otherwise the tests below pass w.r.t uPickle
I'm sure this is an easy question but it's not clear from the example (TapirJsonuPickleTests.scala) how to use a custom encoder/decoder with jsonBody
.
How to reproduce?
package com.example
import org.scalatest.flatspec.AnyFlatSpec
import sttp.tapir._
import sttp.tapir.generic.auto._
import sttp.tapir.json.upickle._
object TapirJsonuPickleCodec extends TapirJsonuPickle
object OptionPickler extends upickle.AttributeTagged {
override implicit def OptionWriter[T: Writer]: Writer[Option[T]] =
implicitly[Writer[T]].comap[Option[T]] {
case Some(x) => x
case None => null.asInstanceOf[T]
}
override implicit def OptionReader[T: Reader]: Reader[Option[T]] =
new Reader.Delegate[Any, Option[T]](implicitly[Reader[T]].map(Some(_))) {
override def visitNull(i: Int) = None
}
}
class TapirJsonSpec extends AnyFlatSpec {
import OptionPickler.{ ReadWriter, macroRW, read }
case class Message(a: String, b: Option[String] = None)
object Message {
implicit val rw: ReadWriter[Message] = macroRW
}
// What does a messageDecoder have to do with `jsonBody`?
// val messageDecoder: JsonCodec[Message] = TapirJsonuPickleCodec.readWriterCodec[Message]
// val baseEndpoint: PublicEndpoint[String, String, Message, Any] = endpoint
// .in(path[String]("id"))
// .errorOut(stringBody)
// .out(jsonBody[Message])
it should "parse json" in {
val str = """{"a": "1", "b": "2"}"""
read[Message](str)
}
it should "handle nulls" in {
val str = """{"a": "1", "b": null}"""
read[Message](str)
}
it should "handle missing values" in {
val str = """{"a": "1"}"""
read[Message](str)
}
}
Metadata
Metadata
Assignees
Labels
No labels