Разница между валидацией и валидатеоптом в JsValue

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?


person Manu Chadha    schedule 26.04.2019    source источник


Ответы (1)


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 привело к успеху.

person Mario Galic    schedule 27.04.2019
comment
Я понимаю ответ, но я борюсь с каким-то другим сценарием. Не могли бы вы взглянуть на stackoverflow.com/questions/55881709/ - person Manu Chadha; 27.04.2019