I am trying to write a Play Framework asynchronous Action for the following URL:
POST /users/:userId/items
My database calls all return Future[...], where ... is Option[A] for find methods and Option[Id] for create methods.
I would like to check for the existence of the userId before trying to create the new item. I have a method Users.findById(userId) that returns a Future[Option[User]]. The result is Some(User) if the user exists and None if not. Items.create() also returns a Future[Option[itemId]].
I am trying to compose something using for:
for {
user <- Users.findById(userId)
if user.isDefined
} yield {
Items.create(...) map { itemId => Ok(itemId) } getOrElse NotFound
}
I would like to return Ok(itemId) if the item is successfully created. I'm not sure how to handle the error case. I would like to return NotFound if either the userId is invalid or the item cannot be created (maybe a field conflicts with a unique value already in the database).
I'm not sure what to put after the for structure. I tried getOrElse, but that does not compile, since Future does not have a getOrElse method.
Ideally, I can handle URLs containing several ids to check, e.g.:
PUT /users/:userId/foo/:fooId/bar/:barId
and confirm that userId, fooId, and barId are all valid before doing the update. All of those calls (Users.findById, Foo.findById, and Bar.findById) will return Future[Option[A]].