Scala Play JSON Пользовательская проверка OneOf - PullRequest
0 голосов
/ 01 марта 2019

Как проверить json, где обязателен один из двух ключей.

Ex1: действительный Json

{
    "userName": "MyName",
    "userId": 123
}

Ex2: действительный Json

{
    "userName": "MyName"
}

Ex3: действительный Json

{
    "userId": 123
}

Ex4: InValid Json - отсутствует UserName и userId

{
    "email": "email@email.com"
}

Мой класс дел ниже

case class FindUser(userName: Option[String], userId: Option[Int]
object FindUser {
  implicit val findUserReads = Json.reads[FindUser]
}

Контроллер:

request.body.validate[FindUser]

1 Ответ

0 голосов
/ 01 марта 2019

В качестве одного из решений вы можете реализовать свои собственные def reads(json: JsValue): JsResult[A]:

import play.api.libs.json._

case class FindUser(userName: Option[String], userId: Option[Int])

object FindUser {
  implicit val findUserReads: Reads[FindUser] = new Reads[FindUser] {
    override def reads(json: JsValue): JsResult[FindUser] = {
      // Read and validate `userName` node
      val nameJsRes: JsResult[Option[String]] = (json \ "userName").validateOpt[String]
      // Read and validate `userId`
      val idJsRes: JsResult[Option[Int]] = (json \ "userId").validateOpt[Int]

      // For-comprehension which will fail fast
      // It will give JsError if:
      //  - nameJsRes is invalid
      //  - idJsRes is invalid
      //  - name and is are empty
      for {
        name <- nameJsRes
        id <- idJsRes
        result <- if (name.isEmpty && id.isEmpty) {
          JsError(JsonValidationError("Either `userName` or `userId` must be set"))
        }
        else {
          JsSuccess(FindUser(name, id))
        }
      } yield result
    }
  }

  def main(args: Array[String]): Unit = {
    // JsSuccess(FindUser(Some(123),Some(1123)),)
    println(Json.parse(
      """{
        |    "userName": "123",
        |    "userId": 1123
        |}""".stripMargin).validate[FindUser])

    // JsSuccess(FindUser(None,Some(1123)),)
    println(Json.parse(
      """{
        |    "userNameXXX": "123",
        |    "userId": 1123
        |}""".stripMargin).validate[FindUser])

    // JsSuccess(FindUser(Some(123),None),)
    println(Json.parse(
      """{
        |    "userName": "123",
        |    "userIdXXX": 1123
        |}""".stripMargin).validate[FindUser])

    // JsError(List((,List(JsonValidationError(List(Either `userName` or `userId` must be set),WrappedArray())))))
    println(Json.parse(
      """{
        |    "userNameXXX": "123",
        |    "userIdXXX": 1123
        |}""".stripMargin).validate[FindUser])
  }
}
...