mkorszun
mkorszun

Reputation: 4571

Scala Spray Routing - two HTTP method directives executed for single request

Here is my routing:

pathPrefix("event" / Segment / "user") { id =>
    pathEnd {
        put {
            dbService.addParticipant(id, user)
            complete("OK")
        } ~
        delete {
            dbService.removeParticipant(id, user)
            complete("OK")
        }
    }
} ~  

When sending PUT or DELETE request to http://localhost:9999/event/860852c4-768f-430e-9a9d-d1d35e86ede2/user both method directives are executed - I mean dbService.addParticipant(id, user) and dbService.removeParticipant(id, user) are called. Could anyone explain me where is the problem here?

I do not see how this differs from official spray example:

// extract URI path element as Int
pathPrefix("order" / IntNumber) { orderId =>
  pathEnd {
    // method tunneling via query param
    (put | parameter('method ! "put")) {
      // form extraction from multipart or www-url-encoded forms
      formFields('email, 'total.as[Money]).as(Order) { order =>
        complete {
          // complete with serialized Future result
          (myDbActor ? Update(order)).mapTo[TransactionResult]
        }
      }
    } ~
    get {
      // JSONP support
      jsonpWithParameter("callback") {
        // use in-scope marshaller to create completer function
        produce(instanceOf[Order]) { completer => ctx =>
          processOrderRequest(orderId, completer)
        }
      }
    }
  }

Upvotes: 1

Views: 429

Answers (1)

dk14
dk14

Reputation: 22374

As @jrudolph pointed out, code inside non-leaf extraction directive (like inside pathPrefix("order" / IntNumber) { orderId => as it takes orderId parameter that is gonna be extracted from request) is executed per every request regardless wether or not directives inside are hitting the route. Code inside leaf-directive (like complete) is executed only when route matches.

To achieve what you probably want, just move your dbService.addParticipant inside complete:

pathPrefix("event" / Segment / "user") { id =>
    pathEnd {
        put {
            complete {
              dbService.addParticipant(id, user)
              "OK"
            }
        } ~
        delete {
            complete {
              dbService.removeParticipant(id, user)
              "OK"
            }
        }
    }
}

Upvotes: 2

Related Questions