Clojure has no built-in HTTP server, but the de facto standard for serving basic, synchronous HTTP requests is the Ring library.

Ring is the basis for most web applications in Clojure. It provides a low-level and straightforward request/response API, where requests and responses are plain old Clojure maps. Ring applications are architected around handlers: functions that accept requests and return responses.

For more details check the Ring API Documentation.

The following example was adapted from parts of chapter 7 of the “Clojure Cookbook” by Luke VanderHart and Ryan Neufeld.

  1. Create a Leiningen application called webapp1. At the terminal type:

    lein new app webapp1

    Run your application for the first time:

    lein run

    The output should just be:

    Hello, World!
  2. Modifiy the webapp1/project.clj file. Update the Clojure version after :dependencies key and also add the ring and compojure libraries, like this:

    File: webapp1/project.clj
    :dependencies [[org.clojure/clojure "1.9.0"]
                   [ring "1.6.3"]
                   [compojure "1.6.1"]]
  3. Replace the full content of the webapp1/src/webapp1/core.clj file with the following code:

    File: webapp1/src/webapp1/core.clj
    ;;;; A Simple Web Server in Clojure.
    ;;;; Uses the Ring library.
    
    (ns webapp1.core
      (:require [ring.adapter.jetty :refer [run-jetty]]
                [ring.middleware.file :refer [wrap-file]]))
    
    (def port 8080)
    
    (defn not-found [request] ; (1)
      {:status   404
       :headers  {"content-type" "text/plain; charset=utf-8"}
       :body     (str "Resource not found: " (:uri request))})
    
    (def app (wrap-file not-found "public")) ; (2)
    
    (defn -main [] ; (3)
      (run-jetty app {:port port}))
    1 This is a handler that produces a response when a requested resource was not found.
    2 The directory at the given root-path "public" is checked for a static file with which to respond to the request, proxying the request to the not-found handler if such a file does not exist.
    3 This is the application’s (web server) entry point.
  4. Create a public directory inside the the root webapp1 directory. In the terminal type:

    cd webapp1
    mkdir public

    All public static content should be placed in this public directory.

  5. Create a webapp1/public/index.html file with the following content:

    File: webapp1/public/index.html
    <!DOCTYPE html>
    <!-- A simple default web page. -->
    <html>
      <head lang="en">
        <meta charset="utf-8">
        <title>Test</title>
      </head>
      <body>
        <h1>Test</h1>
        <p>This is a web page.</p>
      </body>
    </html>
  6. Run the application (web server). From the root webapp1 directory, type at the terminal:

    lein run
  7. Test the web server. In your browser’s address bar, type the corresponding URL:

    http://server-name:8080

    where server-name is the name or IP address of the web server.

    If you’re using a Cloud9 environment, you can obtain this name with the following terminal command:

    echo $C9_HOSTNAME

    You should see the index.html document correctly rendered in your web browser.