This manual is a work in progress and is currently incomplete.
If you'd like to help improve it, and we hope you do, please see the README.

12 Static Assets

Ratpack provides support for serving static files as responses.

1.12 From a directory

Ratpack applications have a notion of a “base dir”, which is specified at launch time. This is effectively root of the filesystem as far as the application is concerned. Files from the base dir can be served, using the Chain.files() method.

import ratpack.test.embed.EmbeddedApp;
import ratpack.test.embed.EphemeralBaseDir;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Example {
  public static void main(String... args) throws Exception {
    EphemeralBaseDir.tmpDir().use(baseDir -> {
      baseDir.write("public/some.text", "foo");
      baseDir.write("public/index.html", "bar");

      EmbeddedApp.of(s -> s
        .serverConfig(c -> c.baseDir(baseDir.getRoot()))
        .handlers(c -> c
          .files(f -> f.dir("public").indexFiles("index.html"))
        )
      ).test(httpClient -> {
        assertEquals("foo", httpClient.getText("some.text"));
        assertEquals("bar", httpClient.getText());
        assertEquals(404, httpClient.get("no-file-here").getStatusCode());
      });

    });
  }
}

Files will be served with a Last-Modified header based on the file’s advertised last modified timestamp. If the client sends an If-Modified-Since header, Ratpack will respond with a 304 response if the file has not been modified since the given value. Served files do not include ETags.

By default, files will be GZIP compressed over the wire if the client asks for it. This can be disabled on a per request basis by calling the Response.noCompress() method. This is typically used by putting a handler in front of the file serving handler that inspects the request path (e.g. file extension) and disables compression.

2.12 Ad-hoc files

Individual files can be served by using the Context.file() and Context.render() methods.

import ratpack.test.embed.EmbeddedApp;
import ratpack.test.embed.EphemeralBaseDir;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Example {
  public static void main(String... args) throws Exception {
    EphemeralBaseDir.tmpDir().use(baseDir -> {
      baseDir.write("some.text", "foo");

      EmbeddedApp.of(s -> s
        .serverConfig(c -> c.baseDir(baseDir.getRoot()))
        .handlers(c -> c
          .get("f", ctx -> ctx.render(ctx.file("some.text")))
        )
      ).test(httpClient ->
        assertEquals("foo", httpClient.getText("f"))
      );

    });
  }
}

If the file returned by Context.file() doesn’t exist, a 404 will be issued.

Responses are timestamped and compressed in exactly the same manner as described for the Chain.files() method.

3.12 Advanced Asset serving with “Asset Pipeline”

The Asset Pipeline project offers an integration with Ratpack. This provides advanced asset bundling, compiling and serving.