Skip to content

Instantly share code, notes, and snippets.

@TylerPachal
Last active April 19, 2017 19:52
Show Gist options
  • Select an option

  • Save TylerPachal/f324aa3e2e5cd154c3a43b2f90a91e8a to your computer and use it in GitHub Desktop.

Select an option

Save TylerPachal/f324aa3e2e5cd154c3a43b2f90a91e8a to your computer and use it in GitHub Desktop.
Play! Json validation that considers more than one field
/* This is a small example of how to use Play! Json to validate a JsValue, when you need to consider a combination
* of fields. In this example, I have ContactInfo, where either a phone number or an email address have to provided
* (or both). Each field is represented as a simple String, when in reality you may want to do further validation
* on each field to make sure it is a valid phone number and/or email.
*/
import play.api.libs.json._
object Main {
case class ContactInfo(phoneNumber: Option[String], email: Option[String])
implicit object ContactInfoReads extends Reads[ContactInfo] {
private val emailKey = "email"
private val phoneNumberKey = "phoneNumber"
override def reads(json: JsValue): JsResult[ContactInfo] = {
val maybePhoneNumber = (json \ phoneNumberKey).asOpt[String]
val maybeEmail = (json \ emailKey).asOpt[String]
if (maybePhoneNumber.isEmpty && maybeEmail.isEmpty) {
JsError(s"Either ${JsPath() \ phoneNumberKey} must be provided, or ${JsPath() \ emailKey} must be provided")
}
else {
JsSuccess(ContactInfo(maybePhoneNumber, maybeEmail))
}
}
}
def main(args: Array[String]): Unit = {
val test1 = Json.obj("phoneNumber" -> "1-800-123-4567").as(ContactInfoReads)
println(test1)
// Output: ContactInfo(Some(1-800-123-4567),None)
val test2 = Json.obj("email" -> "[email protected]").as(ContactInfoReads)
println(test2)
// Output: ContactInfo(None,Some([email protected]))
val test3 = Json.obj("phoneNumber" -> "1-800-123-4567", "email" -> "[email protected]").as(ContactInfoReads)
println(test3)
// Output: ContactInfo(Some(1-800-123-4567),Some([email protected]))
val test4 = Json.obj("somethingElse" -> 991).as(ContactInfoReads)
println(test4)
// Output: Exception in thread "main" play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(List(Either /phoneNumber must be provided, or /email must be provided),WrappedArray())))))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment