2

I am using circe in scala and have a following requirement :

Let's say I have some class like below and I want to avoid password field from being serialised then is there any way to let circe know that it should not serialise password field?

In other libraries we have annotations like @transient which prevent field from being serialised ,is there any such annotation in circe?

case class Employee(                   
                     name: String,
                     password: String)
Hitesh
  • 432
  • 3
  • 13

3 Answers3

1

You could make a custom encoder that redacts some fields:

implicit val encodeEmployee: Encoder[Employee] = new Encoder[Employee] {
  final def apply(a: Employee): Json = Json.obj(
    ("name", Json.fromString(a.name)),
    ("password", Json.fromString("[REDACTED]")),
  )
}

LATER UPDATE

In order to avoid going through all fields contramap from a semiauto/auto decoder:

import io.circe.generic.semiauto._

implicit val encodeEmployee: Encoder[Employee] =
  deriveEncoder[Employee]
    .contramap[Employee](unredacted => unredacted.copy(password = "[REDACTED]"))
gatear
  • 946
  • 2
  • 10
1

Although @gatear's answer is useful, it doesn't actually answer the question.

Unfortunately Circe (at least until version 0.14.2) does not have annotations to ignore fields. So far there is only a single annotation (@JsonKey) and this is used to rename field names.

In order to ignore a field when serialising (which Circe calls encoding) you can avoid that field in the Encoder implementation.

So instead of including the password field:

implicit val employeeEncoder: Encoder[Employee] =
  Encoder.forProduct2("name", "password")(employee => (employee.name, employee.password))

you ommit it:

implicit val employeeEncoder: Encoder[Employee] =
  Encoder.forProduct1("name")(employee => (u.name))

Alternatively what I've been using is creating a smaller case class which only includes the fields I'm interested in. Then I let Circe's automatic derivation kick in with io.circe.generic.auto._:

import io.circe.generic.auto._
import io.circe.syntax._

case class EmployeeToEncode(name: String)

// Then given an employee object:
EmployeeToEncode(employee.name).asJson
Daniel
  • 8,655
  • 5
  • 60
  • 87
1
deriveEncoder.mapJsonObject(_.remove("password"))
FunctorPrototype
  • 1,173
  • 2
  • 12
  • 24