Search code examples
routesakkahrefakka-http

Akka HTTP response html string with recurrent css or image link


I'm implementing a simple web server on Scala with akka http routes dsl and so on. I have (for instance):

val route = get {
    path("test") {
      complete((new ViewTemplate).response)
    }
}

Where ViewTemplateis a class who reads some html template, injects it with some values probably makes some transformations and returns as HttpResponse...

class ViewTemplate(val filename: String = "test.html") {
    import scala.io.Source
    private val template = Source.fromResource(filename)
    override def toString: String = template.mkString
    def entity: ResponseEntity = HttpEntity(ContentTypes.`text/html(UTF-8)`, toString)
    def response: HttpResponse = HttpResponse(entity = entity)
}

all this works fine until i add

<link rel="stylesheet" href="style.css"/>

into test.html's head. The browser just ignores this refs at all. The same situation with images and a's stuff. I suppose, that things like spray of play handle this case fine and I'm inventing another bicycle, but i'm just looking for roots. So what can you advice?


Solution

  • To add an explanation, what you have there is only serving the generated template, it does not serve any other paths, which means that when your browser asks for "http://yourserver/style.css" the server will reply with 404 not found since there is no route defined for "/style.css".

    In Akka HTTP (and Spray as well) you have to explicitly define routes for everything you want your web server to do. You can however define routes that extracts the path from a request and serves corresponding files from the filesystem.

    You can see the various directives for doing this on this page of the docs: http://doc.akka.io/docs/akka-http/10.0.7/scala/http/routing-dsl/directives/file-and-resource-directives/index.html

    Note that getFromResourceDirectory, which you have found yourself, serves files from the classpath and not directly from the filesystem, which may or may not suit your use case.