tapir
tapir copied to clipboard
JSON codec maps None to empty body, keeps content type
Currently, Codec#json(), used by TapirJsonCirce, will interpret an output type of Option[*] as designating an optional body: If the value is None, the response will override the underlying JSON codec's rendering to null and produce an empty body instead, which is no legal JSON, but still declare a content type of application/json.
import sttp.tapir._
import sttp.tapir.json.circe._
val codec = implicitly[Codec[String, Option[String], CodecFormat.Json]]
s"${codec.format.mediaType}: '${codec.encode(None)}'" // application/json: ''
This could either be helped by omitting the Content-type header upon empty body (and perhaps forcing a 204 status code?), or by removing the in-band signaling, i.e. encoding Option values according to the underlying codec and handling the optional body case elsewhere.
Discussion: https://softwaremill.community/t/why-map-none-to-empty-string-in-json-codec/381