Мне кажется, что центральная проблема здесь (как вы упомянули) заключается в том, что Option[String]
выражает 2 состояния, тогда как на самом деле вам требуется 3, а именно:
- значение присутствует и не равно нулю * Значение 1005 *
- присутствует, а значение NULL
- отсутствует
Один из способов решить эту проблему - заключить поля в новый тип
case class PatchField[T](value: Option[T])
Это позволит вам написать класс запроса следующим образом:
case class PatchUserRequest (
firstName: Option[PatchField[String]],
lastName: Option[PatchField[String]]
)
Это означает, что ваши полезные данные теперь будут иметь следующую форму:
{
"firstName": {"value" : "Foo" },
"lastName": {"value" : "Bar" }
}
{
"firstName": {"value": "Foo"}
}
{
"firstName": {"value": null}
}
Я не являюсь конечно, если есть способ принудительно установить, что Circe различает guish между нулем и значениями, которые вообще отсутствуют, но я чувствую, что это может быть хорошим компромиссом.