0
votes

I have a case class with some val (which is not a constructor param). How can I get those fields also in the generated json ?

I was using Json4s before, and used FieldSerializer which did this trick. But unable to get this with Circe.

What I want is to define all the required fields in a trait, sometimes, the field may be a part of the case class. But there are cases, where it doesn't make sense to keep them as part of case class, but still needed in the json. Please note the difference between EntityWithBodyParams and AnotherEntity below.

Here is my sample case class.

trait NamedEntity {
    def name:String
}

case class EntityWithBodyParams(id:Long) extends NamedEntity {
  override val name:String = "Name"
}

case class AnotherEntity(id:Long, name:String) extends NamedEntity 

Response after asJson

{
  "id" : 100
}

But my expectation is :

{
  "id" : 100,
  "name":"Name"
}
2

2 Answers

0
votes

You can create your own Encoder.

import io.circe.{Encoder, Json}

case class EntityWithBodyParams(id: Long) {
  val name: String = "Name"
}

implicit val encoder: Encoder[EntityWithBodyParams] = new 
Encoder[EntityWithBodyParams] {
  override def apply(entity: EntityWithBodyParams): Json = Json.obj(
    "id"   -> Json.fromLong(entity.id),
    "name" -> Json.fromString(entity.name)
  )
}

Reason for this behavior is fact that circe auto encoder uses only product fields of case class. More info you can find here https://github.com/milessabin/shapeless

0
votes

Try writing your case class like this instead.

case class EntityWithBodyParams(id:Long, val name:String = "Name")