Scala Spray Routing Syntax
Asked Answered
S

1

5

Here's the code from an example:

import spray.routing.SimpleRoutingApp

object Main extends App with SimpleRoutingApp {

      implicit val system = ActorSystem("my-system")

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

Found at http://spray.io/documentation/1.1-SNAPSHOT/spray-routing/#spray-routing

Please forgive my noobiness, as I come from a Java background... I'm trying to pick up the Scala language as well this framework at the same time. I semantically understand what's happening here, but syntactically I'm very confused.

I'd like to understand what constructs in the Scala language are applied here, specifcally starting from the call to "startServer" and the implementation in between the {}. That way I can Google it up and research it...but I'm not sure what to look up here. I think it may be related some of the functional concepts in the language.

"startServer" seems to be a method of the SimpleRoutingApp, but it looks like you are passing in nested functions into its body, i.e "path", "get", "complete" ...How does this exactly work? Thanks for all the help.

Siriasis answered 30/6, 2014 at 6:20 Comment(0)
F
7

Spray is not the easiest thing to learn, especially when you just started with Scala, but i'll try to explain.

The first thing you need to understand is currying. In two words curried function is a function which returns another function. So startServer is a good example of a curried function, here it's shortened signature:

def startServer(interface: String, port: Int)(route: ⇒ Route): Future[Http.Bound]

This is one way to declare a curried function, startServer takes a host and a port, then "return" a function which takes your service route and returns a future with Http.Bound. Next trick which is allowed in Scala, is that you can write one arg list in curly braces like {}, and this is used in startServer, the first arg list contains two required parameters, so you can't use {} style, only (), but when you pass host:port, you have a function Route => Future[Http.Bound], so you can apply this style. And this rule can be applied further (with path, get, complete).

What you have inside, i.e

path("hello") {
    get {
      complete {
          <h1>Say hello to spray</h1>
      }
   }
}

is your actual service Route. It consists of so called directives, which are based on shapeless implementation of HList (i won't explain it here, but you can find info out there). In general each directive is a function which does something with user HttpRequest (basically RequestContext). Description for all directives can be found here.

Fugue answered 30/6, 2014 at 7:51 Comment(2)
Thanks for the help! Can you point me to some documentation on that syntactic sugar in which a one arg list method can be applied with {} instead of ()? Thanks!Siriasis
@acspd7 from Scala bookFugue

© 2022 - 2024 — McMap. All rights reserved.