How to implement a REST Web Service using Akka?
Asked Answered
F

6

28

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?

Freeboard answered 12/7, 2011 at 18:13 Comment(0)
M
27

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.

Matrilineage answered 12/7, 2011 at 18:45 Comment(8)
I'd loooove for someone to build a version of the Netty+Unfiltered that uses Jetty Continuations and/or Servlet 3.0 Async so I could hook Akka into it like that. I'm very curious to hear about your Akka experiences as a whole, in private if desirable. Keep up the awesome work, √Mudd
Yeah, it time ever permits, I would love to pitch in on getting that added. I know there is already some groundwork there, but it's hard to get a sense of how much work remains to be done. And this being my first foray into websockets (though, I've done a lot with comet, in the past), I'm hesitant about the complications that may be involved.Matrilineage
Er, I meant to say, I know there is already some groundwork in the sense that the work was started to do it directly in Akka. Not sure if anyone has attempted to implement this in Unfiltered via the Jetty/Servlet 3.0 APIs. I should go research that... oh, what I would give for some free time.Matrilineage
I have too little experience on the Unfiltered codebase, but I've been a part of both the Atmosphere project and fixed issues in Mist, so I have a fair amount of Comet experience. Unfortunately Jonas is on vacation right now so I'm gigabusy, but I'd love to see someone pick that up. Unfiltered has excellent performance, so pairing that with asynchronicity would be a killer.Mudd
There is a lot of awesome information here. Thanks for the same.Freeboard
@Thomas How does dropwizard compare to spray or scalatra?Freeboard
Unfiltered's websocket implementation links are brokenEastman
In recent tests ( see glennengstrand.info/software/performance/scala/clojure ) I found that dropwizard was 3 times faster than Clojure on Ring which was comparable to Scala on Finatra which was 3 times faster ( see glennengstrand.info/software/performance/scala/clojure ) than Spray. I like Akka for what it was originally intended which is a Reactive programming environment. It was never intended to be a web app container.Emetic
E
11

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!

Efta answered 28/2, 2012 at 16:52 Comment(0)
S
5

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

}
Shanly answered 4/4, 2013 at 13:4 Comment(1)
I got the following error with example code: scala: could not find implicit value for parameter timeout: akka.util.Timeout new AsyncResult { val is = myActor ? "Do stuff and give me an answer" }Wilkey
M
3

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.

Moribund answered 12/7, 2011 at 18:24 Comment(0)
B
3

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

Bathyscaphe answered 13/3, 2015 at 3:24 Comment(0)
M
0

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.

Mitigate answered 12/3, 2012 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.