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

发布于 2024-11-19 14:21:03 字数 231 浏览 2 评论 0原文

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

还有什么其他选择?

更新1: 基于 Akka 后端实现 REST 的前端哪个更好? - Spray、Scalatra 或 Dropwizard 还是其他?

I intend to implement a pure Akka powered REST based Web API. I am not sure about using spray. I would consider using Scalatra if it is any good. Basically I am interested in using the concurrency benefits of Scala Actor model. I don't want the Servlet container to be an hindrance in that process.

What can be other options?

Update 1:
Which is better frontend for implementing REST based on Akka backend? - Spray, Scalatra or Dropwizard or any other?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

疏忽 2024-11-26 14:21:03

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

更新:自从几年前写下这个答案以来,我开始使用 Spray 专门用于 Akka 的 RESTful 开发。虽然几乎任何 JVM REST 库都可以使用,但 Spray 非常自然地适合 Akka 基于 actor 的模型,并且该库显然已经达到了成熟的水平,可以轻松成为默认选择。即将将 Spray 作为新的 akka-http 模块集成到 Akka 中就清楚地表明了这一点。

The important thing to realize about Akka is that it's not an all-or-nothing environment. You can, to a large degree, mix and match different libraries to compose the system that makes sense for you. For instance, I have written apps that use Dropwizard fronting a backend which uses Akka, without issue. I have also done the same with Clothesline (implemented in Clojure, but with a Scala wrapper). And later this week, I hope to experiment with using Unfiltered's websocket implementation to sit in front of Akka and a RabbitMQ pipe for feeding near real-time data to the client browsers -- I specifically mention this example because the Unfiltered websocket impl sits on top of Netty rather than a servlet container).

Update: Since having written this answer a few years back, I've begun using Spray exclusively for RESTful development with Akka. While pretty much any JVM REST library can be used, Spray fits very naturally into Akka's actor-based model and the library has clearly reached a level of maturity where it can easily be the default choice. The upcoming integration of Spray into Akka as the new akka-http module is a clear indication of this.

丑丑阿 2024-11-26 14:21:03

如果你想要代码来做这件事,那就在这里。我花了一些时间才真正弄清楚发生了什么,因为有大量的例子,并且不清楚它们都在做什么或如何将它们放在一起。事实证明它比我想象的更简单:

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"
  )

希望这有帮助!

If you want the CODE to do it, then here it is. It took me a bit to really figure out what's going on, because there are a TON of examples, and it's not clear what they are all doing or how to put it all together. Turns out it was more simple than I thought:

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
}

And my build.sbt looks like:

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"
  )

Hope this helps!

呆橘 2024-11-26 14:21:03

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

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")
  }

}

For completeness, it seems useful to have a Scalatra example (since the question asked about Scalatra). Here's some example code from the 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")
  }

}
江城子 2024-11-26 14:21:03

HTTP servlet 和许多容器是一种经过考验且值得信赖的技术。 Akka 为您提供自己的嵌入式 servlet 容器的选择,或者您可以与您自己的一起使用

当然,您可以使用 Netty 构建自己的 Web 服务器,并且有一个有趣的 编写- 在网络上了解此内容

HTTP servlets and the many containers out there is a tried and trusted technology. Akka offers you the choice of its own embedded servlet container, or you can use it with your own.

You can, of course, roll your own web server with Netty, and there's an interesting write-up about this on the web.

机场等船 2024-11-26 14:21:03

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

using akka-http (people also call it spray-2.0) which is based on akka-streams.

为你鎻心 2024-11-26 14:21:03

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

我认为 DropWizard 对于各种 JVM Rest 服务来说都是一个不错的选择,包括使用 Akka 进行实际提升的服务。除了其优点的明显原因(基于被证明是“JVM 最好的”库的集合)之外,我喜欢它还因为它在许多其他库/框架遗漏的领域提供了帮助:指标的生成、声明性验证;同时保持事情简单、明确和易于理解。

I don't know why you are suspicious of using a Servlet container as the base -- it does not really limit your choice in any possible way, it just handles basic HTTP server plumbing.
As such, most java service frameworks use servlet API as the basic foundation even if they don't expose that level.

I think DropWizard is a great choice for all kinds of JVM rest services, including ones that use Akka for actual lifting. Besides the obvious reason of its goodness (based on collection of libraries proven to be "JVM's best"), I like it because it helps in areas that many other libs/frameworks leave out: production of metrics, declarative validation; all the while keeping things simple, explicit and understandable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文