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를 가장 어려운 방법으로 만들어 보았습니다.
