Benutzerdefinierte JSON-Überprüfungseinschränkungen in Play Framework 2.3 (Scala)

Ich habe es geschafft, die Formularüberprüfung mit benutzerdefinierten Einschränkungen zu implementieren, aber jetzt möchte ich dasselbe mit JSON-Daten tun.

Wie kann ich benutzerdefinierte Validierungsregeln auf einen JSON-Parser anwenden?

Beispiel: Die POST-Anforderung des Clients enthält einen Benutzernamen username) und ich möchte nicht nur sicherstellen, dass dieser Parameter ein nicht leerer Text ist, sondern auch, dass dieser Benutzer tatsächlich in der Datenbank vorhanden ist.

// In the controller...

def postNew = Action { implicit request =>
    request.body.asJson.map { json =>
        json.validate[ExampleCaseClass] match {
            case success: JsSuccess[ExampleCaseClass] =>
                val obj: ExampleCaseClass = success.get
                // ...do something with obj...
                Ok("ok")
            case error: JsError =>
                BadRequest(JsError.toFlatJson(error))
        }
    } getOrElse(BadRequest(Json.obj("msg" -> "JSON request expected")))
}


// In ExampleCaseClass.scala...

case class ExampleCaseClass(username: String, somethingElse: String)

object ExampleCaseClass {
    // That's what I would use for a form:
    val userCheck: Mapping[String] = nonEmptyText.verifying(userExistsConstraint)

    implicit val exampleReads: Reads[ExampleCaseClass] = (
        (JsPath \ "username").read[String] and
        (JsPath \ "somethingElse").read[String]
    )(ExampleCaseClass.apply _)
}

Das ist soweit ich weiß, aber das stellt nur sicher, dassusername ist ein String.Wie wende ich meine zusätzliche benutzerdefinierte Validierungsregel an?, z.B. um zu überprüfen, ob der angegebene Benutzer wirklich existiert? Ist das überhaupt möglich?

Klar, ich könnte mein @ nehmobj in demcase success Abschnitt in der Aktion und dort zusätzliche Prüfungen durchführen, aber dies scheint nicht sehr elegant, denn dann müsste ich meine eigene Fehlermeldung erstellen und könnte nur BenutzerJsError.toFlatJson(error) für einige Fälle. Nachdem ich stundenlang gesucht und versucht hatte, konnte ich keine Beispiele finden.

Für reguläre Formulare würde ich so etwas verwenden:

// In the controller object...

val userValidConstraint: Constraint[String] = Constraint("constraints.uservalid")({ username =>
    if (User.find(username).isDefined) {
        Valid
    } else {
        val errors = Seq(ValidationError("User does not exist"))
        Invalid(errors)
    }
})

val userCheck: Mapping[String] = nonEmptyText.verifying(userValidConstraint)

val exampleForm = Form(
    mapping(
        "username" -> userCheck
        // ...and maybe some more fields...
    )(ExampleCaseClass.apply)(ExampleCaseClass.unapply)
)


// In the controller's action method...

exampleForm.bindFromRequest.fold(
    formWithErrors => {
        BadRequest("Example error message")
    },
    formData => {
        // do something
        Ok("Valid!")
    }
)

Aber was ist, wenn die Daten als JSON gesendet werden?