Skip to content

Instantly share code, notes, and snippets.

@omnisis
Created March 7, 2017 05:10
Show Gist options
  • Save omnisis/ccafa81fd1a09e088054ed539cf887b2 to your computer and use it in GitHub Desktop.
Save omnisis/ccafa81fd1a09e088054ed539cf887b2 to your computer and use it in GitHub Desktop.
Akka-Http Example
package examples.webserver
import java.sql.Timestamp
import java.util.Date
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.model._
import akka.http.scaladsl._
import akka.stream.scaladsl._
import akka.http.scaladsl.server.Directives._
import akka.stream.ActorMaterializer
import akka.util.ByteString
import examples.models.Tweet
import spray.json._
import scala.concurrent.Future
import scala.io.StdIn
import scala.util.Random
/**
* API Stub
*/
object TweetApi {
import scala.concurrent.ExecutionContext.Implicits.global
def fetchTweets(): Future[List[Tweet]] = {
Future {
List[Tweet](
Tweet("@twitteruser", "hello world", new Timestamp(new Date().getTime))
)
}
}
}
/**
* Mixin for pulling in necessary JSON support
*/
trait MyJsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
object MyJsonProtocol extends DefaultJsonProtocol {
implicit object TimestampFormat extends RootJsonFormat[Timestamp] {
def write(ts: Timestamp) = JsNumber(ts.getTime)
def read(value: JsValue) = value match {
case JsNumber(n) => new Timestamp(n.bigDecimal.longValue())
case _ => deserializationError("long timestamp expected")
}
}
}
import MyJsonProtocol._
implicit val tweet: RootJsonFormat[Tweet] = jsonFormat3(Tweet.apply)
}
trait Utils {
def nowAsTimestamp(): Timestamp = new Timestamp(new Date().getTime)
def intStream(): Source[Int, _] = Source.fromIterator(() => Iterator.continually(Random.nextInt()))
}
object Webserver extends MyJsonSupport with Utils {
val jsonType = ContentTypes.`application/json`
def main(args: Array[String]): Unit = {
implicit val system = ActorSystem("default")
implicit val materializer = ActorMaterializer()
// needed for binding map/flatMap
implicit val executionContext = system.dispatcher
val route =
path("hello") {
get {
complete(HttpEntity(jsonType, """{"message": "Hello World!"}"""))
}
} ~
path("tweet") {
get {
//val TweetApi.fet
complete(Tweet("foo", "this is a tweet", nowAsTimestamp()))
}
} ~
path("tweets") {
get {
val tweets = TweetApi.fetchTweets()
onSuccess(tweets) {
case Nil => complete(StatusCodes.NoContent)
case x :: xs => complete(x :: xs)
}
}
} ~
path("ints") {
get {
complete(HttpEntity(
ContentTypes.`text/plain(UTF-8)`,
intStream().map(n => ByteString(s"$n\n"))
))
}
} ~
path("bad") {
get {
failWith(new RuntimeException("Shit's busted"))
}
}
val bindingFuture = Http().bindAndHandle(route, "localhost", 7777)
println(s"Server online @ http://localhost:7777/\nPress RETURN to stop...")
StdIn.readLine()
bindingFuture
.flatMap(_.unbind())
.onComplete(_ => system.terminate())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment