Reputation: 5882
This is more of a Scala question but inspired by this http-scala example.
val route =
path("hello") {
get {
complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to akka-http</h1>"))
}
}
Based on example path
seems like it could be a curried method that takes String
as first argument and Route
as second although I do not see such implementation in the API. Could someone enlighten me how this works?
Link to docs: http://doc.akka.io/api/akka-http/current/akka/http/javadsl/server/Directives$.html#path(segment:String,inner:java.util.function.Supplier[akka.http.javadsl.server.Route]):akka.http.javadsl.server.Route
Upvotes: 0
Views: 576
Reputation: 17933
No, path
is not a curried function. The API gives the signature:
def path[L](pm: PathMatcher[L]): Directive[L]
Path is a simple unary function that takes in a PathMatcher
and returns a Directive. Path only seems like it is a curried function because Directive
has an apply method which makes it appear to be a function, but it's actually a class.
PathMatcher
By importing Directives._
the following implicit function becomes available:
implicit def _segmentStringToPathMatcher(segment: String): PathMatcher0
Note: PathMatcher0
is defined as PathMatcher[Unit]
since it does not pass the matched value along to the inner Route
.
Calling path with the argument in the example, path("hello")
, is similar to following code:
val directive : Directive[Unit] = path(_segmentStringToPathMatcher("hello"))
Directive
As stated previously, the Directive
has an apply method that lazily takes in a Route:
def apply(v1 : => Route) : Route
So your example code is essentially making the following call:
val route =
directive.apply(get {
complete(HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say hello to akka-http</h1>"))
})
Putting It All Together
Let's simplify the definition of Route
and mock some logic to demonstrate what is happening:
type SimpleRoute : HttpRequest => RouteResult
We can now write a version of path using a higher order function. Our simpler version takes in a String
and returns a function instead of a Directive. It gets a little tricky because the returned function is also higher order:
def simplePath(pathStr : String) : SimpleRoute => SimpleRoute =
(innerRoute : SimpleRoute) => {
//this is the returned SimpleRoute
(request : HttpRequest) => {
if(request.uri.path.toString equalsIgnoreCase pathStr)
RouteResult.Complete(innerRoute(request))
else
RouteResult.Rejected(Seq.empty[Rejection])
}
}
Upvotes: 2