Last active
March 8, 2017 08:41
-
-
Save omnisis/b7ce354565ebb9f3c527c40135925e77 to your computer and use it in GitHub Desktop.
Scala Akka Boilerplate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package examples.utils | |
object AnsiColors { | |
val ANSI_RESET = "\u001B[0m" | |
val ANSI_BLACK = "\u001B[30m" | |
val ANSI_RED = "\u001B[31m" | |
val ANSI_GREEN = "\u001B[32m" | |
val ANSI_YELLOW = "\u001B[33m" | |
val ANSI_BLUE = "\u001B[34m" | |
val ANSI_PURPLE = "\u001B[35m" | |
val ANSI_CYAN = "\u001B[36m" | |
val ANSI_WHITE = "\u001B[37m" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import MyBuild._ | |
import AssemblyKeys._ | |
name := "scala-akka" | |
version := "1.0" | |
scalaVersion := "2.11.8" | |
libraryDependencies ++= Seq( | |
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion, | |
"io.spray" %% "spray-json" % "1.3.3", | |
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion, | |
"com.typesafe.akka" %% "akka-slf4j" % akkaVersion, | |
"com.typesafe.scala-logging" %% "scala-logging" % "3.5.0", | |
"ch.qos.logback" % "logback-classic" % "1.1.2", | |
"com.lihaoyi" %% "sourcecode" % "0.1.3" | |
) | |
assemblySettings | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<configuration> | |
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | |
<encoder> | |
<pattern>%green(%date{ISO8601}) [%25.25(%X{sourceThread})] %highlight(%-5level) %-30.30logger{30} -- %msg%n</pattern> | |
</encoder> | |
</appender> | |
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> | |
<appender-ref ref="STDOUT" /> | |
</appender> | |
<root level="debug"> | |
<appender-ref ref="ASYNC"/> | |
</root> | |
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package examples.server | |
import java.sql.Timestamp | |
import java.util.Date | |
import akka.actor.ActorSystem | |
import akka.event.Logging | |
import akka.http.scaladsl.Http | |
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport | |
import akka.http.scaladsl.model._ | |
import akka.http.scaladsl.server.Directives._ | |
import akka.stream.ActorMaterializer | |
import akka.stream.scaladsl._ | |
import akka.util.ByteString | |
import examples.models.Tweet | |
import examples.utils.Colors | |
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 Main extends Object | |
with MyJsonSupport | |
with Utils | |
with LoggingSupport { | |
import Colors._ | |
println(s"${ANSI_CYAN}:::::${ANSI_RESET} Now Running ${ANSI_BLUE}MB${ANSI_RESET}${ANSI_RED}Flask${ANSI_RESET} ${ANSI_CYAN}:::::${ANSI_RESET}") | |
val jsonType = ContentTypes.`application/json` | |
implicit val system = ActorSystem("default") | |
implicit val materializer = ActorMaterializer() | |
val log = Logging(system, this) | |
def main(args: Array[String]): Unit = { | |
// 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) | |
log.info(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