I need to get an entire case class, built with 3 other case classes, back in one call. However, depending on a users credentials they may or may not have access to certain parts of that case class.
Below is how I'm currently doing it.(and it works) It's making the call but clearing out the unauthorized case classes afterwards. I would ideally like to stop the call (due to low bandwidth) if they don't have the proper credentials and return None.
The persistent entity service call is expecting an Option[PersonOne] and Option[PersonTwo] so the .ask must return that or it says it's returning an object and won't compile.
override def getPerson(id: UUID, credOne: Option[Boolean], credTwo: Option[Boolean]) = ServerServiceCall { _ =>
for {
g <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonGeneral)
h <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonOne) //if (credOne) **this 'if' does not work**
s <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonTwo)
} yield {
val x: Option[PersonOne] = if (credOne == Some(true)) h else None
val y: Option[PersonTwo] = if (credTwo == Some(true)) s else None
CompletePerson(g.get, x, y)
//TODO catch if no employee is returned
//throw NotFound (s"Person not Found with $id");
}
}
Here is a version of your function that will only call ask
if the appropriate credential value is Some(true)
:
override def getPerson(id: UUID, credOne: Option[Boolean], credTwo: Option[Boolean]) = ServerServiceCall { _ =>
CompletePerson(
registry.refFor[PersonEntity](id.toString()).ask(GetPersonGeneral).get,
credOne.filter(_ == true).flatMap(_ => registry.refFor[PersonEntity](id.toString()).ask(GetPersonOne)),
credTwo.filter(_ == true).flatMap(_ => registry.refFor[PersonEntity](id.toString()).ask(GetPersonTwo))
)
}
The key part is this:
credX.filter(_ == true).flatMap(...)
credX
is None
this will return None
credX
contains false
it will return None
credX
is Some(true)
then flatMap
will call the ask
functionask
returns None
then the expression will return None
, otherwise it will return Some[PersonX]
I am a bit unclear on some of the data types, but I think this should give you some idea of how to approach this code. (For example, that bare .get
look dangerous as it could throw an exception)
I fixed an issue with the filter(_)
, it should be filter(_ == true)
.
It looks like ask
actually returns Option[Option[T]]
, in which case this might be closer to what is needed.
def getPerson(id: UUID, credOne: Option[Boolean], credTwo: Option[Boolean]) = ServerServiceCall { _ =>
for {
g <- registry.refFor[PersonEntity](id.toString()).ask(GetPersonGeneral)
gen <- g
} yield {
val p1 = credOne.filter(_ == true).flatMap(_ => registry.refFor[PersonEntity](id.toString()).ask(GetPersonOne))).flatten
val p2 = credTwo.filter(_ == true).flatMap(_ => registry.refFor[PersonEntity](id.toString()).ask(GetPersonTwo))).flatten
CompletePerson(gen, p1, p2)
}
}