Skip to content


Subversion checkout URL

You can clone with
Download ZIP
tree: f4e21a97d5
Fetching contributors…

Cannot retrieve contributors at this time

57 lines (48 sloc) 1.654 kb
(ns com.clojurebook.url-shortener
(:use [compojure.core :only (GET PUT POST defroutes)])
(:require (compojure handler route)
[ring.util.response :as response]))
(def ^:private counter (atom 0))
(def ^:private mappings (ref {}))
(defn url-for
(@mappings id))
(defn shorten!
"Stores the given URL under a new unique identifier, or the given identifier
if provided. Returns the identifier as a string.
Modifies the global mapping accordingly."
(let [id (swap! counter inc)
id (Long/toString id 36)]
(or (shorten! url id)
(recur url))))
([url id]
(when-not (@mappings id)
(alter mappings assoc id url)
(defn retain
[& [url id :as args]]
(if-let [id (apply shorten! args)]
{:status 201
:headers {"Location" id}
:body (format "URL %s assigned the short identifier %s" url id)}
{:status 409 :body (format "Short URL %s is already taken" id)}))
(defn redirect
(if-let [url (url-for id)]
(response/redirect url)
{:status 404 :body (str "No such short URL: " id)}))
(defroutes app*
(GET "/" request "Welcome!")
(PUT "/:id" [id url] (retain url id))
(POST "/" [url] (if (empty? url)
{:status 400 :body "No `url` parameter provided"}
(retain url)))
(GET "/:id" [id] (redirect id))
(GET "/list/" [] (interpose "\n" (keys @mappings)))
(compojure.route/not-found "Sorry, there's nothing here."))
(def app (compojure.handler/api app*))
;; ; To run locally:
;; (use '[ring.adapter.jetty :only (run-jetty)])
;; (def server (run-jetty #'app {:port 8080 :join? false}))
Jump to Line
Something went wrong with that request. Please try again.