Skip to content

Start a serverλ︎

The very basics of starting an Http server with Jetty or Httpkit.

Projects containing application servers are typically started from the command line, especially when deployed.

During development an application server is typically managed via the REPL, either calling a or via a component lifecycle service (mount, integrant, component)

The -main functionλ︎

The -main function is used to capture optional arguments to set configuration such as port and ip address. These values can either be passed as function arguments, operating system environment variables or default values.

Define a -main function that optionally takes an argument that will be used as a port number to listen for requests.

A value is bound to the local name port using either the argument to the -main function, an operating system environment variable or the default port number.

(defn -main
  "Start the application server on a specific port"
  [& [port]]
  (let [port (Integer. (or port
                           (System/getenv "PORT")
                           8080))]
    (server-start port)))

The app-server-start function starts a specific application server, eg. Jetty, http-kit-server.

Listen on Portλ︎

Application servers listen on a specific port for messages over HTTP/S which is set when starting the application server. Public facing application will receive requests over port 80, although for security reasons a firewall or proxy is placed in front of the application server which redirects traffic to an internal port number for the application server.

Cloud application platforms (Heroku, Google, AWS) provide a port number each time a new cloud environment (eg. container) is provisioned, so an application server should read in this dynamically assigned port number from the provided operating system environment variable.

Integer type port numberλ︎

(Integer. port-number) will cast either a string or number to a JVM integer type. (Integer/parseInt port-number) is also commonly used and has the same result.

These functions are used to ensure an Integer type value is passed to the application server. As Clojure uses Java application servers (Java app servers have decades of development) then the correct type must be passed to avoid error.

Get environment variablesλ︎

A common way to get environment variables from the operating system is to use the Java method, System/getenv.

(System/getenv "PORT") returns the value of the `PORT` environment variable.  If the variable is not set, then nil is returned (TODO: check what is actually returned)

Clojure WebApps - set port in shell and read port using System/getenv function

System/getProperty method will get specific values from Java .properties files, usually from a system.properties file in the root of the project. System/getProperties will get all properties found in .properties files in the project. Settings typically found in the system.properties files include version of Java

java.runtime.version=11

The Java Tutorials: Properties

(System/getenv) returns a hash-map of all current environment variables. Wrap in a def name to make a useful REPL tool to inspect the current environment variables available.

(comment
  ;; Get all environment variables
  ;; use a data inspector to view environment-variables name
  (def environment-variables
    (System/getenv))
  )

Use tools such as the clojure inspector or data inspector tools in Clojure aware editors (e.g. CIDER inspector)

Environ library for environment variablesλ︎

Use environment variables as Clojure keywords.

weavejester/environ library will source environment settings from Leiningen and Boot configurations, the Operating System and Java system property files. The library works for Clojure and ClojureScript projects.

Include environ/environ.core library as a dependency in the Clojure project configuration

Require the library in the web-service namespace ns form

(require '[environ.core :refer [env]])

Then call the env function with a property name to return the value associated with that property.

(env :port)