Static resource reload with akka-http
Asked Answered
W

3

7

In short: is it possible to reload static resources using akka-http?

A bit more:

  • I have Scala project.
  • I'm using App object to launch my Main class.
  • I'm using getFromResourceDirectory to locate my resource folder.

What I would like to have is to hot-swap my static resources during development. For example, I have index.html or application.js, which I change and I want to see changes after I refresh my browser without restarting my server. What is the best practise of doing such thing?

I know that Play! allows that, but don't want to base my project on Play! only because of that.

Weighting answered 22/7, 2016 at 10:45 Comment(1)
Take a look at sbt-revolver pluginTestamentary
S
5

Two options:

  1. Easiest: use the getFromDirectory directive instead when running locally and point it to the path where your files you want to 'hotload' are, it serves them directly from the file system, so every time you change a file and load it through Akka HTTP it will be the latest version.
  2. getFromResourceDirectory loads files from the classpath, the resources are available because SBT copies them into the class directory under target every time you build (copyResources). You could configure sbt using unmanagedClasspath to make it include the static resource directory in the classpath. If you want to package the resources in the artifact when running package however this would require some more sbt-trixery (if you just put src/resources in unmanagedClasspath it will depend on classpath ordering if the copied ones or the modified ones are used).
Short answered 27/7, 2016 at 12:7 Comment(1)
Wow, that was so easy.. :) I was using 'getFromResourceDirectory'. Thanks!Weighting
M
3

I couldn't get it to work by adding to unmanagedClasspath so I instead used getFromDirectory. You can use getFromDirectory as a fallback if getFromResourceDirectory fails like this.

val route =
  pathSingleSlash {
    getFromResource("static/index.html") ~
    getFromFile("../website/static/index.html")
  } ~
  getFromResourceDirectory("static") ~
  getFromDirectory("../website/static")

First it tries to look up the file in the static resource directory and if that fails, then checks if ../website/static has the file.

Michellmichella answered 2/7, 2018 at 2:29 Comment(0)
R
1

The below code try to find the file in the directory "staticContentDir". If the file is found, it is sent it back to the client. If it is not found, it tries by fetching the file from the directory "site" in the classpath. The user url is: http://server:port/site/path/to/file.ext

/site/ comes from "staticPath"

  val staticContentDir = calculateStaticPath()
  val staticPath = "site"
  val routes = pathPrefix(staticPath) {
    entity(as[HttpRequest]) { requestData =>
      val fullPath = requestData.uri.path
      encodeResponse {
        if (Files.exists(staticContentDir.resolve(fullPath.toString().replaceFirst(s"/$staticPath/", "")))) {
          getFromBrowseableDirectory(staticContentDir.toString)
        } else {
          getFromResourceDirectory("site")
        }
      }
    }
  }

I hope it is clear.

Rooks answered 7/9, 2016 at 22:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.