Spray routing works for single slash but nothing else

80 Views Asked by At

So i have asked about this before and have changed a lot of code around.

Spray Routing Doesn't match anything

Now I am executing my functions that return HTTPresponses insided detach() blocks so that i dont block. These then are completed and return to the client, but I still can't seem to get my routing to work.

In my tests, a request to a single slash works fine, but anything else, such as this create user path shown below fails. I can't seem to figure out why, and spray routing uses so many constructs I'm having a hard time figuring out how the system works well enough to find out whats happening.

I tried inserting logRequest blocks around certain paths thinking that might show me whats happening, but none of them seem to get hit. Any help would be greatly appreciated.

val route: Route = {
    host("fakebook.com", "www.fakebook.com") {
      pathSingleSlash {
        complete("pong")
      } ~
        pathPrefix("users") { req =>
            path("newuser") {
                put {
                  detach() {
                    complete(genericPut(CreateUser(req.request)))
                  }
                }
            } ~
            ... rest of routing

And here is what my scalatests look like, the simple Put passes, but the put with newuser doesn't

val createUserSuccessRequest = Put(Uri("http://www.fakebook.com/users/newuser") withQuery(F_User.lastNameString -> "Doe", F_User.firstNameString -> "John", F_User.bioString -> "i like foobar",
    F_User.ageString -> "42", F_User.dobString -> dateFormatter.format(new Date(1970 - 1900, 5, 7))))

 "The FakeBook route" when {

    "When sending a single slash request" should {
      "respond with a simple pong" in {
        Get() ~> logRequestResponse("plain get final request and response")(sealRoute(route)) ~> check {
          assert(responseAs[String] == "pong")
        }
      }
    }

    "Running route to create a user with PUT" should {
      "forward a message to the backbone to create a new user" in {
        createUserSuccessRequest ~> logRequest("create user final request and response"){sealRoute(route)} ~> check {
          expectMsg(CreateUser(createUserSuccessRequest))
        }
      }
    }
  }
1

There are 1 best solutions below

0
On

For anyone else trying to solve this issue:

a lot of these directives actually DONT extract anything, so having the lambda inputs i have like req => and req2 => will not work.

It turns out, spray routing is designed so that you never have to touch the RequestContext as I have done with my functions (which is why I try to access it). They extract only the useful data. Rather than do things as I should and change my function signatures, i am going to (for now) do a hotfix that has worked.

if you absolutely must have the requestcontext, so long as you don't break it somehow, you can extract it by making your own extraction directive like so val extractRequestContext = extract(x => x) and wrap your code in that

I did this

path("somepath") {
     detach() {
          extractRequestContext { request => complete(someFunc(request)) }
     }
}

In the future I should learn to use the DSL more correctly and extract what I need from the request context using directives and pass THOSE to the functions