longevity

A Persistence Framework for Scala and NoSQL

View project on GitHub

UserServiceImpl.updateUser

Here’s the code for UserServiceImpl.updateUser:

  def updateUser(username: String, info: UserInfo): Future[Option[UserInfo]] = {
    {
      for {
        retrieved <- repo.retrieveOne[User](Username(username))
        modified = retrieved.modify(info.mapUser)
        updated <- repo.update(modified)
      } yield {
        Some(UserInfo(updated.get))
      }
    } recover {
      case e: DuplicateKeyValException[_, _] => handleDuplicateKeyVal(e, info)
      case e: NoSuchElementException => None
    }
  }

This method shows a variation on repo.retrieve: repo.retrieveOne. retrieveOne opens up the Option for you, throwing a NoSuchElementException if the Option is empty. We handle the NoSuchElementException in the recover clause, returning None if the User was not found. Akka HTTP will handle the None by returning a 404 Not Found, which is exactly what we want.

The retrieved in the for comprehension is a PState[User]. Calling retrieved.modify produces another PState[User] that reflects the changes produced by the function passed to modify. In this case, we call UserInfo.mapUser, which updates a User according to the information in the UserInfo. The resulting PState is stored in a local value named modified.

We then pass modified on to repo.update. This method persists the changes, but like repo.create, it might generate a DuplicateKeyValException if we try to update the user to have a conflicting username or email. Once again, we handle this problem in the recover clause, converting the longevity exception into a Simple Blogging service exception.

prev: UserServiceImpl.retrieveUser
up: getting started guide
next: exercising the api