Skip to content

Instantly share code, notes, and snippets.

@jcromartie
Created March 29, 2013 16:47
Show Gist options
  • Save jcromartie/5272024 to your computer and use it in GitHub Desktop.
Save jcromartie/5272024 to your computer and use it in GitHub Desktop.
An example of generic HTTP CRUD operations over a ref holding a simple map-based data model
(ns foo.web.util
"Utilities shared by various web namespaces"
(:use compojure.core)
(:require [foo.json :as json]
[foo.model :refer (uuid)]))
(defn json-response
"Return a Ring response with the appropriate JSON content type
header and a JSON representation of obj in the body."
[obj & flags]
{:body (json/encode obj)
:headers {"Content-Type" "application/json"}
:status (cond
(some #{:created} flags) 201
(:errors obj) 400
:else 200)})
(defn no-content
"Returns a Ring response for HTTP 204 No Content"
[]
{:status 204})
;; CRUD routes for repos
(defn crud-validate-and-save
[repo key obj validate render]
(let [errors (validate obj)]
(if (empty? errors)
(let [id (:id obj (uuid))
obj (assoc obj :id id)]
(dosync
(alter repo update-in [key] assoc id obj))
(json-response (render obj)))
(json-response {:errors errors}))))
(defn crud-routes
"Returns a handler implementing simple CRUD operations on objects in
repo ref under nested collection key with given parse (from params),
validate, and render functions"
[repo key parse validate render]
(routes
(GET "/" []
(json-response (->> repo deref key vals (map render))))
(POST "/" [& params]
(let [obj (parse params)]
(crud-validate-and-save repo key obj validate render)))
(GET "/:id" [id]
(if-let [obj (get-in @repo [key id])]
(json-response (render obj))
{:status 404}))
(PUT "/:id" [id & params]
(let [obj (assoc (parse params) :id id)]
(crud-validate-and-save repo key obj validate render)))
(DELETE "/:id" [id]
(dosync (alter repo update-in [key] dissoc id))
(no-content))))
@jcromartie
Copy link
Author

it would be better to have a store/delete function than take a ref and a key like that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment