首页 文章

如何使用Akka实现REST Web服务?

提问于
浏览
28

我打算实现一个纯Akka驱动的基于REST的Web API . 我不确定使用喷雾剂 . 如果有任何好处,我会考虑使用Scalatra . 基本上我对使用Scala Actor模型的并发优势感兴趣 . 我不希望Servlet容器成为该过程中的障碍 .

还有什么其他选择?

更新1:哪个是基于Akka后端实现REST的更好前端? - 喷雾,Scalatra或Dropwizard或任何其他?

6 回答

  • 5

    关于Akka的重要一点是,它不是一个全有或全无的环境 . 您可以在很大程度上混合和匹配不同的库来组成对您有意义的系统 . 例如,我编写的应用程序使用Dropwizard前端使用Akka,没有问题 . 我也使用了Clothesline(在Clojure中实现,但使用了Scala wrapper) . 本周晚些时候,我希望尝试使用Unfilteredwebsocket implementation坐在Akka和RabbitMQ管道前面向客户端浏览器提供近实时数据 - 我特别提到这个例子,因为Unfiltered websocket impl位于Netty的顶部,而不是servlet容器) .

    Update :自从几年前写过这个答案以来,我已经开始使用Spray专门用于Akka的RESTful开发 . 虽然几乎可以使用任何JVM REST库,但Spray非常自然地适用于Akka的基于actor的模型,并且库已经明显达到了成熟度,它可以很容易地成为默认选择 . 即将推出的Spray与Akka的整合作为新的akka-http模块清楚地表明了这一点 .

  • 27

    如果你想让CODE这样做,那么就在这里 . 我花了一些时间才弄清楚发生了什么,因为有一些TON的例子,并不清楚他们在做什么或如何把它们放在一起 . 事实证明它比我想象的更简单:

    package com.nthalk.akkatest
    
    import akka.actor.Actor.actorOf
    import akka.actor.Actor
    import akka.camel.Consumer
    import akka.camel.Message
    import akka.camel.CamelServiceManager
    
    class MyActor extends Actor with Consumer {
      def endpointUri = "jetty:http://localhost:8877/"
      def receive = {
        case msg: Message => { self.reply("State Rest Service: Achieved") }
        case _ => { self.reply("Really, no message?") }
      }
    }
    
    object App extends scala.App {
      actorOf[MyActor].start
      CamelServiceManager.startCamelService
    }
    

    我的build.sbt看起来像:

    organization := "com.nthalk"
    
    name := "akkatest"
    
    version := "0.1.0"
    
    resolvers += 
      "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"
    
    libraryDependencies ++= Seq(
      "org.apache.camel" % "camel-jetty" % "2.9.0",
      "se.scalablesolutions.akka" % "akka-camel" % "1.3.1"
      )
    

    希望这可以帮助!

  • 10

    为了完整起见,有一个Scalatra示例似乎很有用(因为有关Scalatra的问题) . 以下是Scalatra Akka Guide的一些示例代码:

    package com.example.app
    
    import akka.actor.{ActorRef, Actor, Props, ActorSystem}
    import akka.dispatch.ExecutionContext
    import akka.util.Timeout
    import org.scalatra.FutureSupport
    import org.scalatra.{Accepted, ScalatraServlet}
    
    class MyActorApp(system:ActorSystem, myActor:ActorRef) extends ScalatraServlet with     FutureSupport {
    
      protected implicit def executor: ExecutionContext = system.dispatcher
    
      import _root_.akka.pattern.ask
      implicit val timeout = Timeout(10)
    
      get("/async") {
        new AsyncResult { def is = myActor ? "Do stuff and give me an answer" }
      }
    
      get("/fire-forget") {
        myActor ! "Hey, you know what?"
        Accepted()
      }
    }
    
    class MyActor extends Actor {
      def receive = {
        case "Do stuff and give me an answer" => sender ! "The answer is 42"
        case "Hey, you know what?" => println("Yeah I know... oh boy do I know")
      }
    
    }
    
  • 3

    HTTP servlet和许多容器都是经过尝试和信任的技术 . Akka为您提供its own embedded servlet container的选择,或者您可以使用with your own .

    当然,您可以使用Netty推送自己的Web服务器,并且有一个有趣的write-up about this on the web .

  • 0

    使用基于akka-streams的akka-http(人们也称之为spray-2.0) .

  • 3

    我不知道为什么你怀疑使用Servlet容器作为基础 - 它并没有以任何可能的方式限制你的选择,它只是处理基本的HTTP服务器管道 . 因此,大多数java服务框架使用servlet API作为基础,即使它们不公开该级别 .

    我认为DropWizard是各种JVM休息服务的绝佳选择,包括使用Akka进行实际提升的服务 . 除了显而易见的原因(基于被证明是“JVM最佳”的库的集合),我喜欢它,因为它有助于许多其他lib /框架遗漏的领域:指标的生成,声明性验证;一直保持简单,明确和易懂的东西 .

相关问题