I have an empty case class corresponding to an HTTP GET request:
case class GetFoo() extends MyQueryRequest {
// ...
}
and each message has a companion object with describes its implicit JSON writer and reader:
object GetFoo extends MyImplicitJsonProvider[GetFoo] {
implicit val write = Json.writes[GetFoo]
implicit val read = Json.reads[GetFoo]
}
However, because GetFoo
takes no parameters, there's no way to (de)serialize it:
Unapply of object
GetFoo
has no parameters. Are you using an empty case class?
A workaround to inject a dummy Boolean variable into the constructor for GetFoo
, but this is a kludge. I'd like to make GetFoo
(de)serializable as an empty JSON object. How can I do that?
Since GET requests don't send data, it would be even better to make the reader/writer throw an exception if it were being used since the request shouldn't need to be written or read ever, but is required by the extended class.
My design relies on the GetX
class extending MyQueryRequest
and and the GetX
companion object extending MyImplicitJsonProvider[GetX]
.
Throwing an error
If you just want to have non implemented implicit values, you may very well do
implicit def format: Format[GetFoo] = ???
This will add the implicit in the scope whenever you need it, but will throw a NotImplementedException
if it is invoked.
Dummy serialization
If you want (de)serialization as empty JsObject
, just implement it as such:
implicit val nonStrictReads = Reads.pure(GetFoo()) // does not check anything on the `JsValue`, always give a `JsSuccess(GetFoo())`
implicit val strictReads = Reads[GetFoo](json => json.validate[JsObject].filter(_.values.isEmpty).map(_ => GetFoo())
implicit val writes = OWrites[GetFoo](_ => Json.obj())
Better catch it while you can
However, it would be better to catch the error at compile time, by ensuring (through stronger typing) that your request has no content. To do this, I would need more information on MyQueryRequest
and MyImplicitJsonProvider
to help you, but I would imagine doing something like MyQueryRequest[NoContent]
or MyQueryRequest[JsValue]
depending on when you have some content or not. Then one would require JSON serializer, while the other would not.
By the way, you might want to replace your empty case class by a case object, to avoid unnecessary multiple allocations (unless you do some ).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With