Interactive Development

squiddle edited this page Feb 11, 2013 · 14 revisions

When developing with Ring, you may find yourself wanting to reload your source files without restarting your development server.

There are three ways of doing this:

I. Using Lein-Ring

The easiest way is to use the lein-ring plugin for Leiningen. To use it, first add it as a development dependency to your project.clj file:

:dev-dependencies [[lein-ring "0.5.4"]]

And run the following shell command to download and install that dependency:

lein deps

Then add the following key to the end of your project.clj file:

:ring {:handler your-app.core/handler}))

This tells the lein-ring plugin where your main Ring handler is, so replace your-app.core/handler with the namespace and symbol of your own handler function.

When you've done that, you can start a new server at the command line with:

lein ring server

The server will automatically reload any modified files in your source directory.

II. Using Ring-Serve

If you're using an integrated environment, like Emacs with SLIME, you may want to start your development server inside your development environment. This will give you the ability to set break points and step through your code.

The ring-serve library provides a function to make this easy to do. First, add ring-serve as a development dependency to your project.clj file:

for leiningen 1.x users you add ring-serve to the development dependencies like this

:dev-dependencies [[ring-serve "0.1.1"]]

for leiningen 2.x users you have to add the dependencies of the :dev profile like this

:profiles {:dev {:dependencies [[ring-serve "0.1.2"]]}}

Then download and install the dependency with the following shell command:

lein deps

You can now start a new development server at the REPL using the ring.util.serve/serve function:

user> (require 'your-app.core/handler)
user> (use 'ring.util.serve)
user> (serve your-app.core/handler)
Started web server on port 3000

III. Manually

If you don't want to use the aforementioned tools, you can set things up manually. This option is for more advanced users who know what they're doing.

Ensure that:

  • Your Ring adapter is running in a background thread so it doesn't block your REPL.
  • Your handler function is wrapped in a var, so it will be updated when you reload the namespace.

For example:

user> (defonce server (run-jetty #'handler {:port 8080 :join? false}))