3

Assuming I have a folder foo with an index.html file in it and the following minimal (but most likely not functional) server code for Akka HTTP below:

object Server extends App {
  val route: Route =
    pathPrefix("foo") {
      getFromDirectory("foo")
    }

  Http().bindAndHandle(route, "0.0.0.0", 8080)
}

index.html will correctly be served if I open http://localhost:8080/foo/index.html in a browser, but not if I open http://localhost:8080/foo or http://localhost:8080/foo/.

If this is even possible, how can I set up my Akka HTTP routes to serve index.html files within that location by default?

I know I could do the following:

val route: Route =
  path("foo") {
     getFromFile("foo/index.html")
  } ~
  pathPrefix("foo") {
    getFromDirectory("foo")
  }

But:

  • This only makes http://localhost:8080/foo work, not http://localhost:8080/foo/
  • This is very ad-hoc and does not apply globally: if I have a foo/bar/index.html file, the problem will be the same.
astorije
  • 2,666
  • 2
  • 27
  • 39

1 Answers1

3

You can create the Route you are looking for by using the pathEndOrSingleSlash Directive:

val route =
  pathPrefix("foo") {
    pathEndOrSingleSlash {
      getFromFile("foo/index.html")
    } ~ 
    getFromDirectory("foo")
  }

This Route will match at the end of the path and feed up the index.html, or if the end doesn't match it will call getFromDirectory instead.

If you want to make this "global" you can make a function out of it:

def routeAsDir[T](pathMatcher : PathMatcher[T], dir : String) : Route = 
  pathPrefix(pathMatcher) {
    pathEndOrSingleSlash {
      getFromFile(dir + "/index.html")
    } ~ 
    getFromDirectory(dir)
  }

This can then be called with

val barRoute = routeAsDir("foo" / "bar", "foo/bar")

Functional Akka Http

Side note: your code is completely functional. The elegance of the Directives DSL can be a bit misleading and convince you that you've accidentally strayed back into imperative programming style. But each of the Directives is simply a function; can't get more "functional" than that...

Ramón J Romero y Vigil
  • 17,373
  • 7
  • 77
  • 125