Spray(5)REST API Project - Recall and Prepare Project

Spray(5)REST API Project - Recall and Prepare Project

1. Recall some ideas
These things consist of all the modules we are using.
spray-can, spray-routing, spray-io, spray-http, spray-util, spray-testkit, spray-json

How we deal with HTTP
def receive = {
case HttpRequest(HttpMethods.GET, "/", _, _, _) =>
sender ! index
case HttpRequest(HttpMethods.GET, "/stop", _, _, _) =>
sender ! HttpResponse(entity = "Shutting down in 1 second ...")
context.system.scheduler.scheduleOnce(1 second span, new Runnable { def run() { context.system.shutdown() } })
case HttpRequest(GET, "/server-stats", _, _, _) =>
valclient = sender
(context.actorFor("../http-server") ? HttpServer.GetStats).onSuccess {
casex: HttpServer.Stats => client ! statsPresentation(x)
}

case HttpRequest(GET, "/io-stats", _, _, _) =>
valclient = sender
(IOExtension(context.system).ioBridge() ? IOBridge.GetStats).onSuccess {
case IOBridge.StatsMap(map) => client ! statsPresentation(map)
}
case HttpRequest(HttpMethods.GET, "/event", _, _, _) =>
sender ! ok

}

Spray Routing
class MyService extends Actor with HttpServiceActor {
def receive = handleTimeouts orElse runRoute(myRoute)

def myRoute: Route = `<my-route-definition>`

def handleTimeouts: Receive = {
case Timeout(x: HttpRequest) =>
sender ! HttpResponse(StatusCodes.InternalServerError, "Too late")
} }

The ~ operator was introduced, which connects two routes in a way that allows a second route to get a go at a request if the first route "rejected" it.

Spray-json
Then I can parse the string to AST abstract Syntax Tree(AST).
1.1. String to AST
valjson1 = """{ "streetNumber": "A1", "street" : "Main Street", "city" : "Colombo" }"""
valjson2 = """{ "name" : "John", "age" : 26, "sex" : 0 , "address" : { "streetNumber": "A1", "street" : "Main Street", "city" : "Colombo" }}"""

//string to AST
valaddressAST = json1.asJson //or JsonParser(source)
valpersonAST = json2.asJson

1.2. AST to String
//AST to string
println(addressAST.compactPrint) //or .compactPrint
println(personAST.prettyPrint)

1.3. AST to Object
import AddressJsonProtocol._
//AST 2 Object
val address1 = addressAST.convertTo[Address]

1.4. Object to AST
//Object 2 AST
valaddressAST2 = address1.toJson


Slick
Do with slick and native SQL.

2. Prepare a New Project
I need to add something to build.sbt to make some sbt commands works.
sbt>re-start
sbt>re-stop
sbt>assembly

build.sbt
import AssemblyKeys._
seq(Revolver.settings: _*)


mainClass in assembly := Some("com.sillycat.easysprayrestserver.Boot")

artifact in (Compile, assembly) ~= { art =>
art.copy(`classifier` = Some("assembly"))
}

excludedJars in assembly <<= (fullClasspath in assembly) map { cp =>
cp filter {_.data.getName == "parboiled-scala_2.10.0-RC1-1.1.3.jar"}
}


addArtifact(artifact in (Compile, assembly), assembly)

Do remember to change the mainClass in assembly.

project/build.properties
sbt.version=0.12.1

project/Build.scala
import sbt._
import Keys._

object ApplicationBuild extends Build {

lazyvalmain = Project(id = "easysprayrestserver",
base = file("."), settings = Project.defaultSettings).settings()

}


project/plugins.sbt
addSbtPlugin("io.spray" % "sbt-revolver" % "0.6.2")

addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0")


addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.8.5")

Then we can do the command like this
Start the application with default configuration
sbt>re-start

Stop the application
sbt>re-stop

Build the binary file
sbt>assembly

Run the application directly from Java
>java -Dconfig.file=/path/application.conf -jar LocalpointAPI-assembly-0.1.jar

And there is another configuration file.
src/main/resources/application.conf
build.env = ""
build.env = ${?env}
server {
address = "0.0.0.0"
port = 9000
}environment {app1 { server { address = "0.0.0.0" port = 9001 }}
app2 { server { address = "0.0.0.0" port = 9002 }}

}

The application which will use this configuration will be
val config = ConfigFactory.load()
val env = config.getString("build.env")
var serverAddress: String = config.getString("server.address")
var serverPort: Int = config.getInt("server.port")

if (env != null && env != "") {
serverAddress = if (config.getString("environment." + env + ".server.address") != null) config.getString("environment." + env + ".server.address") elseserverAddress
serverPort = if (config.getInt("environment." + env + ".server.port") != 0) config.getInt("environment." + env + ".server.port") elseserverPort
}


newHttpServer(handler) ! Bind(interface = serverAddress, port = serverPort)

Then the command will be
Open the port 9001
sbt>re-start --- -Dbuild.env=app1

Open the port 9002
sbt>re-start --- -Dbuild.env=app2

Open the default port 9000
sbt>re-start

3. How to Write Test
come soon…

4. How to Work with Actor
come soon…

5. How to Work with Logback
come soon…

Tips
1. Eclipse is so slow
I try to download and use eclipse from type safe
http://typesafe.com/stack/downloads/scala-ide
And install the JGit for it
http://download.eclipse.org/egit/updates


References:
spray
http://sillycat.iteye.com/blog/1766558
http://sillycat.iteye.com/blog/1766568
http://sillycat.iteye.com/blog/1767203
http://sillycat.iteye.com/blog/1768065

slick
http://sillycat.iteye.com/blog/1767204
http://sillycat.iteye.com/blog/1767865

Source codes
https://github.com/spray/spray
http://spray.io/documentation/spray-testkit/
https://github.com/spray/spray-template
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值