Actor모델로 설계된 인사하는 액터에 , RestAPI를 연결해보자
액터의 메시지 처리기법중 ASK 패턴 은 결과를 기다려야하는 RestAPI와 연동이 가능하다.
다양한 액터 메시지 패턴과 더 우아하게 Http에 연결하고자 할때 Akka Http 를 활용할수도 있지만
여기서는 간단하게 Actor를 PlayFramework내에서 사용하는 방법을 알아보자
Dependency
build.sbt
val akkaVersion = "2.5.8" libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-actor" % akkaVersion, "com.typesafe.akka" %% "akka-stream" % akkaVersion, "com.typesafe.akka" %% "akka-slf4j" % akkaVersion, // Only if you are using Akka Testkit "com.typesafe.akka" %% "akka-testkit" % akkaVersion % Test, "com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion % Test )
Actor
actors/HelloActor.scala
package actors import akka.actor._ object HelloActor { def props = Props[HelloActor] case class SayHello(name: String) } class HelloActor extends Actor { import HelloActor._ def receive = { case SayHello(name: String) => sender() ! "Hello, " + name } }
SCALA의 OOP는 아직 적응이 안되지만, 인사를 받으면 응답해주는 액터설계를 위와같이 할수가 있다
Controller
controllers/Application.scala
package controllers import actors.HelloActor import actors.HelloActor.SayHello import akka.actor._ import akka.pattern.ask import akka.util.Timeout import javax.inject._ import play.api.mvc._ import scala.concurrent.ExecutionContext import scala.concurrent.duration._ @Singleton class Application @Inject() (system: ActorSystem,cc:ControllerComponents) (implicit ec: ExecutionContext) extends AbstractController(cc) { implicit val timeout: Timeout = 5.seconds val helloActor = system.actorOf(HelloActor.props, "hello-actor") def sayHello(name: String) = Action.async { (helloActor ? SayHello(name)).mapTo[String].map { message => Ok(message) } } //... }
Java Spring 의존성 주입을 알고있다면, 위 코드는 스칼라일뿐 형태가 비슷한것을 알수가 있습니다.
의존성 주입은 JAVA뿐만아니라, .NET 웹서비스 작성시에도 사용되는 컨셉이며
디자인 패턴을 사용할수 있는 사용방법을 의미합니다.
의존성 주입이란:
Routes
conf/routes
# Actor Test GET /hello/:name controllers.Application.sayHello(name)
웹주소의 endpoint를 컨트롤로 연결하는 부분으로 routes 라는 별도의 파일에
분리정의를 합니다.
Result
인사에 응답을 하는 API를 가장 어려운 방법으로 만들어 보았습니다.