an introduction – Main features – HTTP Server - spray-can



an introduction – Main features – HTTP Server - spray-can

0 0


preso-spray-intro


On Github nexelem / preso-spray-intro

an introduction

Created by Darek Zon / @darekzon

Agenda

Presentation no. 1 - introduction

Presentation no. 2 - Spray and neo4j, error handling, cache, tests

Presentation no. 3 - Spray and angular

What is Spray?

Tool for building REST/HTTP applications based on Scala and Akka

Main features

Fast and lightweight embedded HTTP server

DSL for constructing API

Marshalling system

Support for Servlet 3.0

Spray Http server is merged into Akka as Akka HTTP

Akka HTTP will be foundation for Play Framework

Benchmarks?

http://spray.io/blog/2013-05-24-benchmarking-spray/

http://blog.xebia.com/2013/08/02/on-the-mysteriously-fast-spray-can-web-server/

Spray modules

spray-can – low level, lightweight and fast HTTP server

spray-client – high lewel HTTP client

spray-caching – fast and lightweight in-memory caching

spray-routing – simple yet powerfull DSL for API constructing

spray-json – Marhalling data using JSON standard

spray-client: authorization, compression, marshalling

spray-servlet: building servlet webapps with spray-routing

What should have simple Spray application?

Http Server binded to IO interface

Defined API

Actors for API calls processing

HTTP Server - spray-can

HTTP pipelining

HTTP persistent connections

SSL/TLS encryption

HTTP Server - pipelining

http://en.wikipedia.org/wiki/HTTP_pipelining

HTTP Server - persistent connections

http://en.wikipedia.org/wiki/HTTP_persistent_connection

Simple example

import spray.routing.SimpleRoutingApp

				    object Main extends App with SimpleRoutingApp {
				      implicit val system = ActorSystem("simle-example")

				      startServer(interface = "localhost", port = 8080) {
					path("hello") {
					  get {
					    complete {
					      <h1>Say hello to spray</h1>
					    }
					  }
					}
				      }
				    }

Configuration

Based on `typesafe config` library

No initial configuration required

Automaticaly search `application.conf` file for configuration

Example configurations

Three types of timeout, `idle`, `request` and `timeout`

max-content-length - maximum content lenght (usefull when sending large files)

stats-support - support for statistics collection

Idle - after timeout idle connection is closed

Request - if request hasn't been responded sent Timedout message to timeout handler

Timeout - if request still hasn't been responded after Timedout message, server sent error response

Statistics - small overhead, switch off for production

Spray routing

type Route = RequestContext => Unit

Does not return results, all processing responses are returned to client by responder from RequestContext

May include simple path as well as path with variables (through PathMatcher system)

MAY BE BLOCKED

Simple example

class UserApi(implicit val actorSystem: ActorSystem) ... {
					def userActor = actorSystem...
					val route =
					  path("user") {
					    post {
					      handleWith { us: User =>
						(userActor ? AddUser(us)).mapTo[User]
					      }
					    } ~
					  path("user" / Segment) { userLogin =>
					    delete {
					      complete {
						"Kasowanie uzytkownika"
					      }
					    }
					  };
				      }

`handleWith` vs `complete`

Both may be used to handle requests/responses

`complete` may handle only marshalling while

handleWith = `unmarshall` + `complete`

Json

Provides marshaller and umarshaller (by implicit mechanism)

New types can be easly added by creating custom formats that extends JsonFormat

Custom date Format

trait CustomFormats {
					  implicit object JsonDateFormat extends JsonFormat[DateTime] {
					    def write(obj: DateTime) = {
					      JsString(obj.toString());
					    }

					    def read(json: JsValue): DateTime = json match {
					      case JsString(date) => DateTime.parse(date)
					      case _ => sys.error("Unable to parse date")
					    }
					  }
					}

Demo