Spray: routing - understand the difference between path and pathPrefix
Asked Answered
D

3

8
import akka.actor.Actor
import spray.routing.HttpService
import spray.http._
import MediaTypes._
import spray.json._
import spray.routing.directives.CachingDirectives._
import spray.httpx.encoding._

trait MarginEvaluationService extends HttpService {
  import ClassSerializer._
  import spray.httpx.SprayJsonSupport._
  val myRoute = {

      pathPrefix("hello") {
        get {
          respondWithMediaType(`text/html`) { // XML is marshalled to `text/xml` by default, so we simply override here
            complete {
              <html>
                <body>
                  <h1>Say hello to <i>spray-routing</i> on <i>spray-can</i>!</h1>
                </body>
              </html>
            }
          }
        }
      }
      ~
      pathPrefix("testjson") {
        get {
          entity(as[TestC]) { c =>
            respondWithMediaType(`application/json`) {
              complete(c)
            }
          }
        }
      }
   }
}

The route is bugged:

Error:(49, 1) illegal start of simple expression pathPrefix("testjson") { ^

What is the difference between path and pathPrefix? I am not sure if the ~ operator is not properly included.

Dribble answered 6/8, 2015 at 14:44 Comment(0)
A
2

In docs :

path(x): is equivalent to rawPathPrefix(slash().concat(segment(x)).concat(pathEnd())). It matches a leading slash followed by x and then the end.

pathPrefix(x): is equivalent to rawPathPrefix(slash().concat(segment(x))). It matches a leading slash followed by x and then leaves a suffix unmatched.

Anadem answered 6/3, 2019 at 14:51 Comment(0)
D
12

path is a final path, while pathPrefix can be subsequently combined with other path segments using the DSL.

If you want to match exactly /hello you should use path("hello").

pathPrefix is convenient in cases like

pathPrefix("hello") {
  path("foo") {
    complete("foo")
  } ~
  path("bar") {
    complete("bar")
  }
}

which will match /hello/foo and /hello/bar.


That having being said, I suspect the error you're getting is simply the scala parser not getting along with the DSL.

Can you try moving the ~ on the same line as the closing brace? I think the parser is inferring a semicolon, so it's really understanding that piece of code as

pathPrefix("hello") {
    get {
      respondWithMediaType(`text/html`) { // XML is marshalled to `text/xml` by default, so we simply override here
        complete {
          <html>
            <body>
              <h1>Say hello to <i>spray-routing</i> on <i>spray-can</i>!</h1>
            </body>
          </html>
        }
      }
    }
  };
  ~
  pathPrefix("testjson") {
    get {
      entity(as[TestC]) { c =>
        respondWithMediaType(`application/json`) {
          complete(c)
        }
      }
    }
  }
Dickdicken answered 6/8, 2015 at 14:47 Comment(1)
it looks like I can not combine pathPrefix with ~Dribble
A
2

In docs :

path(x): is equivalent to rawPathPrefix(slash().concat(segment(x)).concat(pathEnd())). It matches a leading slash followed by x and then the end.

pathPrefix(x): is equivalent to rawPathPrefix(slash().concat(segment(x))). It matches a leading slash followed by x and then leaves a suffix unmatched.

Anadem answered 6/3, 2019 at 14:51 Comment(0)
T
0

pathPrefix(x): This will add a slash before the unmatched (x). For ease of use, we do not have to include the slash in the directive. (Slash ~ x).

path(x): This will add a slash before the unmatched (x), will match (x) and then add a PathEnd. Unmatched path after (x), will be ignored. (Slash ~ x ~ PathEnd)

Threedecker answered 12/12, 2018 at 4:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.