1
votes

I'm using Scala v2.13.1 and AKKA HTTP v10.1.11.

I have a route in the following structure:

def foo(a: String): Directive1[String] = {
    provide(a)
}

def bar(a: String): Directive1[String] = {
    provide(a)
}

val route: Route =
    get {
        foo("a") { v =>
            bar(v) { v2 =>
                complete(s"Received: $v2")
            }
        }
    }

I have methods like foo and bar that receive some argument, perform some logic, and return Directive1[String].

I want to use foo and bar outside the route and use them together (in the same logical order in the current route), so I did:

def foobar(a: String): Directive1[String] = {
    foo(a) { v =>
        bar(v) { v2 =>
            provide(v2)
        }
    }
}

val route: Route =
    get {
        foobar("a") { v =>
                complete(s"Received: $v")
        }
    } 

And I expected the same results.

Unfortunately foobar doesn't work, and I don't seem to understand why.

The error:

type mismatch;
 found   : akka.http.scaladsl.server.Directive1[String]
    (which expands to)  akka.http.scaladsl.server.Directive[(String,)]
 required: akka.http.scaladsl.server.RequestContext => scala.concurrent.Future[akka.http.scaladsl.server.RouteResult]
                provide(v2)

How can I get the behaviour of foobar?

1

1 Answers

4
votes

Use flatMap:

def foo(a: String): Directive1[String] = {
  provide(a)
}

def bar(a: String): Directive1[String] = {
  provide(a)
}

def foobar(a: String): Directive1[String] = {
  foo(a).flatMap(v => bar(v))
}

val route: Route =
  get {
    foobar("a") { v =>
      complete(s"Received: $v")
    }
  }