Created
March 29, 2013 16:47
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
it would be better to have a store/delete function than take a ref and a key like that