Skip to content
Mike Walker edited this page Mar 16, 2020 · 8 revisions

Web applications often need to serve static content, such as images or stylesheets. Ring provides two middleware functions to do this.

One is wrap-file. This serves static content from a directory on the local filesystem:

(use 'ring.middleware.file)
(def app
  (wrap-file your-handler "/var/www/public"))

This will wrap a handler such that the directory at the given root-path is checked for a static file with which to respond to the request, proxying the request to the wrapped handler if such a file does not exist.

The other is wrap-resource. This serves static content from the JVM classpath:

(use 'ring.middleware.resource)
(def app
  (wrap-resource your-handler "public"))

If you're using a Clojure build tool like Leiningen then the non-source-file resources for a project are kept in the resources directory. Files in this directory are automatically included in jar or war files.

So in the above example, files placed in the resources/public directory will be served up as static files.

Often you'll want to combine wrap-file or wrap-resource with other middleware, usually wrap-content-type and wrap-not-modified:

(use 'ring.middleware.resource
     'ring.middleware.content-type
     'ring.middleware.not-modified)

(def app
  (-> your-handler
      (wrap-resource "public")
      (wrap-content-type)
      (wrap-not-modified))

The wrap-content-type middleware chooses a content-type based on the file extension. For instance, a file called hello.txt would get a content-type of text/plain.

The wrap-not-modified middleware checks the Last-Modified header on the response against the If-Modified-Since header on the request. This saves bandwidth by ensuring clients don't need to download resources they've already cached.

Note that this extra middleware needs to wrap around (i.e. come after) the wrap-resource or wrap-file functions.

Next Page - Content Types

Clone this wiki locally