Skip to content

Instantly share code, notes, and snippets.

@matsu-chara
Last active May 23, 2017 01:42
Show Gist options
  • Save matsu-chara/87e4b651964165940c6b39d50801d69d to your computer and use it in GitHub Desktop.
Save matsu-chara/87e4b651964165940c6b39d50801d69d to your computer and use it in GitHub Desktop.
finatra風?コントローラ
import com.twitter.util.Future
import scala.reflect.ClassTag
// generated code
case class FooReqThrift(value: Int)
case class ThriftException(message: String, cause: Throwable) extends RuntimeException(message, cause)
// libs
abstract class RequestAdapter[ReqThrift, ReqDto] {
def adapt(a: ReqThrift): Future[ReqDto]
}
abstract class ResponseAdapter[ResDto, ResThrift, ResException] {
def adapt(a: ResDto): Future[ResThrift]
def handle(e: ResException): ThriftException
}
class Gateway[ReqThrift, ReqDto, ResDto, ResThrift, ResException: ClassTag](
requestAdapter: RequestAdapter[ReqThrift, ReqDto],
responseAdapter: ResponseAdapter[ResDto, ResThrift, ResException]) {
def open(args: ReqThrift)(useCase: ReqDto => Future[ResDto]): Future[ResThrift] = {
val response = for {
reqDto <- requestAdapter.adapt(args)
resDto <- useCase(reqDto)
thrift <- responseAdapter.adapt(resDto)
} yield thrift
response.rescue {
case e: ResException =>
Future.exception(responseAdapter.handle(e))
}
}
}
object Gateway {
def apply[ReqThrift, ReqDto, ResDto, ResThrift, ResException: ClassTag](
requestAdapter: RequestAdapter[ReqThrift, ReqDto],
responseAdapter: ResponseAdapter[ResDto, ResThrift, ResException]
) = new Gateway(requestAdapter, responseAdapter)
}
// usecase specific
case class FooReqDto(value: Int)
@Singleton
class object FooRequestAdapter extends RequestAdapter[FooReqThrift, FooReqDto] {
override def adapt(a: FooReqThrift): Future[FooReqDto] = Future(FooReqDto(a.value))
}
case class FooResDto(value: Double)
case class FooResThrift(value: Double)
@Singleton
class FooResponseAdapter extends ResponseAdapter[FooResDto, FooResThrift, FooAppException] {
def adapt(a: FooResDto): Future[FooResThrift] = Future(FooResThrift(a.value))
def handle(e: FooAppException): ThriftException = ThriftException(e.message, e.cause)
}
object FooController {
def foo(args: FooReqThrift): Future[FooResThrift] = {
Gateway(new FooRequestAdapter, new FooResponseAdapter).open(args) { reqDto =>
Future(FooResDto(reqDto.value.toDouble * 2))
}
}
}
// usage
FooController.foo(FooReqThrift(1))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment