I follow the design of the book Functional and Reactive Domain Modeling
And for some service methods, it only delegates work to the repository layer. Is there a way to reduce this boilerplate :
trait FeedbackServiceImpl extends FeedbackService {
override def saveTFE(feedback: TripFeedbackEvent) =
Kleisli[Future, Context, Either[String, Id]] { ctx => ctx.feedbackRepo.save(feedback) }
override def saveLFE(feedback: LibraryFeedbackEvent) =
Kleisli[Future, Context, Either[String, Id]] { ctx => ctx.feedbackRepo.save(feedback) }
override def findByUser(userId: Id) =
Kleisli[Future, Context, Seq[FeedbackEvent]] { ctx => ctx.feedbackRepo.findByUser(userId) }
override def all =
Kleisli[Future, Context, Seq[FeedbackEvent]] { ctx => ctx.feedbackRepo.all }
override def findByTip(tipId: Id) =
Kleisli[Future, Context, Seq[FeedbackEvent]] { ctx => ctx.feedbackRepo.findByTip(tipId) }
}
We can create a combinator :
private def kleisli[M[_], A](f: FeedbackRepository => M[A]) =
Kleisli.kleisli(f).local[Context](_.feedbackRepo)
Hence we gain 2 things :
ctx.feedbackRepo
by using local
So we can use :
trait Feedbacks {
def saveTFE(feedback: TripFeedbackEvent) = kleisli(_.save(feedback))
def saveLFE(feedback: LibraryFeedbackEvent) = kleisli(_.save(feedback))
def findByUser(userId: Id) = kleisli(_.findByUser(userId))
...
}