If you are expecting to receive either a Json of a type A
or type B
(Either[A, B]
), how could you write a decoder for it?
For example, let's say you are building a client for an external API that can answer with some expected Json structure:
{
"fieldA": "value",
"fieldB": "value2"
}
or if something fails, it will answer with an object with an error
field:
{
"error": "Your request was wrong"
}
And then you want to have an instance with either of those structures:
val response: String = // Response from the server
val decodedValue =
decode[Either[ErrorResponse, ExpectedResponse](response) // (...) <- What implicit to place here?
How can you write a decoder for either one response structure or the other?
From Circe issue 672, you can write a generic decoder for Either in the following way:
implicit def eitherDecoder[A, B](implicit a: Decoder[A], b: Decoder[B]): Decoder[Either[A, B]] = {
val left: Decoder[Either[A, B]]= a.map(Left.apply)
val right: Decoder[Either[A, B]]= b.map(Right.apply)
left or right
}
Note: For this approach, you still need to implicitly define a decoder for A
and for B
. In most cases, using deriveDecoder
is enough.