Last active
May 23, 2017 01:42
-
-
Save matsu-chara/87e4b651964165940c6b39d50801d69d to your computer and use it in GitHub Desktop.
finatra風?コントローラ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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