Преобразование из запроса в User
включает три уровня необязательности (или «пропущенности»):
- может отсутствовать заголовок
"user"
, - значение заголовка может быть недействительным JSON,
- JSON не может иметь правильную форму для десериализации в
User
.
Эта многоуровневая опция может быть элегантно обработана с форс-к-коференцией, которая приведет к None
, если чего-то не хватает на любом уровне, и к Some(user)
, если все хорошо:
def userFromRequest(request: AuthenticatedRequest[A]): Option[User] =
for {
userHeader <- request.headers.get("user") // "user" header may be missing
userJson <- Json.parseOpt(userHeader) // header value may be not valid json
user <- userJson.asOpt[User] // json may be not convertible to user
} yield user
Обратите внимание, что я вынул Future
из логики c, поскольку это преобразование не имеет ничего общего с асинхронными вызовами.
Затем можно реализовать метод getSubject
, вызвав приведенную выше функцию:
override def getSubject[A](request: AuthenticatedRequest[A]): Future[Option[Subject]] =
Future.successful(userFromRequest(request))