Почему в JsValue есть validate и validateOpt - PullRequest
2 голосов
/ 26 апреля 2019

JsValue имеет два метода

def validate[A](implicit rds: Reads[A]): JsResult[A] - Пытается преобразовать узел в JsResult [T] (Успех или Ошибка).

def validateOpt[A](implicit rds: Reads[A]): JsResult[Option[A]] - Я полагаю, это такжеделает то же самое.

В какой ситуации будет использоваться validateOpt?По моему мнению, если JsResult не удастся, я получу ошибку в JsError.Так какой смысл иметь дополнительный слой Option в JsSuccess, так как JsSuccess всегда будет содержать значение после успешного преобразования JsValue в тип A?

1 Ответ

4 голосов
/ 27 апреля 2019

validateOpt следует использовать, если нулевое значение JSON или отсутствующий путь JSON не считаются ошибкой. Например, скажем, у нас есть следующая модель

case class Person(
  name: String
  employer: Option[String]
)

, где поле employer является необязательным, так как это вполне разумно, если человек не работает, хотя у него всегда есть имя. Затем десериализацию следующего JSON

{
  "name": "Picard"
}

должно быть успешным, даже если путь employer отсутствует. Таким образом, ручное определение Reads[Person] будет использовать validateOpt, как, например,

  implicit val personRead: Reads[Person] = Reads { json =>
    for {
      name     <- (json \ "name").validate[String]
      employer <- (json \ "employer").validateOpt[String]
    } yield Person(name, employer)
  }

Также контрастная десериализация null, например

  val raw = "null"
  val json = Json.parse(raw)
  println(json.validate[String])
  println(json.validateOpt[String])

должен вывести

JsError(List((,List(JsonValidationError(List(error.expected.jsstring),WrappedArray())))))
JsSuccess(None,)

где мы видим validateOpt привело к успеху.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...