Я строю следующий API для пользователей в игре Scala:
case class User(_id: BSONObjectId, username: String)
Проблема в том, что когда клиент отправляет запрос на сохранение / создание нового пользователя, _id отсутствует.
Казалось бы, одно жизнеспособное решение:
case class User(_id: Option[BSONObjectId], username: String)
Однако показалось немного раздражающим проверить поле параметра не только для вставки пользователя, но и для других операций CRUD.
Одно из предложений, которое я получил, было два типа:
case class User(name: String) ; type UserWithId = (Id, User)
или
case class User[A](id: A, name: String); type UserWithId = User[BSONObjectId]
type UserWithoutId = User[Unit]
Я выбрал последнюю реализацию, так как она показалась мне подходящей.
Я создал правильные форматы Json для обработки как вставки дел, так и других операций:
object User {
lazy val userWithIdFormat: OFormat[UserWithId] = Json.format[UserWithId]
lazy val userWithoutIdFormat: OFormat[UserWithoutId] = Json.format[UserWithoutId]
}
Однако теперь при вставке я столкнулся с проблемой, как элегантно конвертировать из UserWithoutId => UserwithId после того, как Id был сгенерирован
Итак, следующим шагом было создание этого метода:
case class User[A](_id: A, username: String)
{
def map[B](f: A => B): User[B] = ???
}
Это какой-то тип монады, который мне нужно реализовать? (Сейчас изучаю теорию категорий)
Я полагаю, что самый простой способ - это просто добавить "инициализированное / пустое" состояние, в котором класс Case должен всегда иметь Id, и только когда он сохраняется, он будет иметь имя пользователя.
Что-то вроде val initalizedUser = User(BSONObjectId.generate(), "")
Какой здесь лучший подход?
Использование типов улучшит производительность и сделает домен более насыщенным, или просто добавление состояния сделает его более доступным для будущих коллег
Какой должна быть реализация для map, это то, что я должен извлечь и иметь свою собственную реализацию Monad, которая будет применяться для всех будущих коллекций?
Лучше обратиться к функциональной библиотеке, чтобы решить эту проблему, или еще нет?