I'm trying to add simple validation to incoming Json in Play. Based on this question, I tried writing:
case class ApiData(data: String)
def maxLengthValidator = Reads.StringReads.filter(ValidationError("Error"))(_.length < 100)
implicit val ApiDataReads: Reads[ApiData] = (
(JsPath \ "data").read[String](maxLengthValidator)
)(ApiData.apply _)
This does not compile, producing the error:
type mismatch;
[error] found : String => ApiData
[error] required: play.api.libs.json.Reads[?]
[error] )(ApiData.apply _)
[error] ^
[error] one error found
But if I add a second field, it does compile:
case class ApiData(data: String, __doNotUse: Option[Int])
implicit val ApiDataReads: Reads[ApiData] = (
(JsPath \ "data").read[String](maxLengthValidator) and
(JsPath \ "__doNotUse").readNullable[Int]
)(ApiData.apply _)
What do I need to do to get this working with just a single field?
Since you only have a single field, you don't need the combinator syntax to create a reads, you can just use the functions already defined on Reads
to build the one you want.
def maxLengthValidator = Reads.of[String].filter(ValidationError("Error"))(_.length < 100)
case class ApiData(data: String)
object ApiData {
implicit val reads: Reads[ApiData] = (__ \ "data").read(maxLengthValidator).map(ApiData.apply _)
}
You start with a Reads[String]
, add some validation (filter
) and then transform valid results to your own rich type (map
).
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