Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications...

55
Building CRUD applications in Clojure https://github.com/danielytics/diy-crud/

Transcript of Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications...

Page 1: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

Building CRUD applications in Clojure

https://github.com/danielytics/diy-crud/

Page 2: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

What do we need?

• Request Handler

• Routing

• Database Access

• Templating

Page 3: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD

• Request Handler

• Routing

• Database Access

• Templating

Ring

Compojure, bidi, pedestal, silk, ...

Yesql, korma, lots of others for noSQL databases

Enlive, enliven, selmer, hiccup, clostache, ...

Lots of options!

Page 4: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD

• Request Handler

• Routing

• Database Access

• Templating

Ring

Bidi

Yesql

Erinite/template

Page 5: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD

• Request Handler

• Routing

• Database Access

• Templating

Ring

Bidi

Yesql

Erinite/template

Why ring?

• Defacto standard

Page 6: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD

• Request Handler

• Routing

• Database Access

• Templating

Ring

Bidi

Yesql

Erinite/template

Why bidi?

• Routes are data

• Reversible (URL -> route, route -> URL)

• Clojure and Clojurescript

Page 7: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD

• Request Handler

• Routing

• Database Access

• Templating

Ring

Bidi

Yesql

Erinite/template

Why Yesql?

• Works with JDBC

• Write SQL as SQL

Page 8: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD

• Request Handler

• Routing

• Database Access

• Templating

Ring

Bidi

Yesql

Erinite/template

Why Erinite/template?

• Because I wrote it ;-)

• USP: template manipulation through data

• Will go into more detail later in this talk

Page 9: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD setup a project

$ lein new crud-talk; cd crud-talk; vim project.clj

:dependencies [[org.clojure/clojure “1.7.0”]

[ring “1.4.0-RC1”]

[bidi “1.20.0”]

[yesql "0.4.0“ :exclusions [instaparse]]

[instaparse “1.4.1”] ; For clj 1.7 support

[org.xerial/sqlite-jdbc "3.7.2"]

[hiccup "1.0.5"]

[erinite/template “0.2.0”]]

:plugins [[lein-ring "0.9.6"]]

:ring {:handler crud-talk.core/handler}

Page 10: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD create handler

$ vim src/crud-talk/core.clj

(ns crud-talk.core

(:require

[bidi.ring :as bidi-ring]

[yesql.core :refer [defqueries]]

[erinite.template.core :as t]

[hiccup.core :refer [html]]))

;; Other code goes here...

(def handler (bidi-ring/make-handler routes))

Page 11: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD create our routes

(def routes

["/" {"items"

{{:request-method :get} read-items

{:request-method :post} create-item}

["item/" :item-id]

{{:request-method :get} read-item

{:request-method :put} update-item

{:request-method :post} delete-item

{:request-method :delete} delete-item}}])

Page 12: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD create our routes

(def routes

["/" {"items"

{{:request-method :get} read-items

{:request-method :post} create-item}

["item/" :item-id]

{{:request-method :get} read-item

{:request-method :put} update-item

{:request-method :post} delete-item

{:request-method :delete} delete-item}}])

So we can test in browser without using JS

Page 13: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD read a list of items

-- name: get-all-items

-- Read a summary list of all items in database.

SELECT id, name, quantity

FROM items

Page 14: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD create database queries

(def db-spec {:classname "org.sqlite.JDBC"

:subprotocol "sqlite"

:subname "db.sqlite"})

(defqueries “queries.sql”)

Page 15: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD create database queries

Make sure you have a database setup:

$ sqlite db.sqlite

sqlite> create table items (id int, name text, description text, qunantity int);

sqlite> insert into items values (1, ‘Test item’, ‘A test item. The first one’, 5);

sqlite> insert into items values (2, ‘Another item’, ‘A test item. The second one’, 26);

sqlite> insert into items values (3, ‘Item’, ‘The third item’, 3);

Page 16: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD create template

(def item-list-template

[:div

[:h1 "Item List"]

[:table.items

[:tr

[:td.id] [:td.name] [:td.quantity]

[:td [:form {:method “post”} [:button {:type "submit"} "delete"]]]]]

[:hr] [:div "New item"]

[:form#new {:action "/items“ :method "post"}

[:input.name {:type "text"}]

[:input.description {:type "text"}]

[:input.quantity {:type "text"}]

[:button {:type "submit"} "add"]]])

Page 17: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD transform template

(def item-list-transformations

{[:.items] [:clone-for :items]

[:.items :.id] [:content :id]

[:.items :.name] [:content :name]

[:.items :.quantity] [:content :quantity]

[:.items :form] [:set-attr :action :url]})

Page 18: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD compile template

(def item-list

(t/compile-template

item-list-template

item-list-transformation))

Page 19: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD item list handler

(defn read-items [request]

(let [items (map

#(assoc % :url (str "/item/" (:id %)))

(get-all-items db-spec))]

{:status 200

:body (html (item-list {:items items}))}))

Page 20: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD item list handler

(defn read-items [request]

(let [items (map

#(assoc % :url (str "/item/" (:id %)))

(get-all-items db-spec))]

{:status 200

:body (html (item-list {:items items}))}))

Page 21: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD the data

({:id 1

:name “Test item”

:quantity 5}

{:id 2

:name “Another item”

:quantity 26}

{:id 3

:name “Item”

:quantity 3})

Page 22: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD item list handler

(defn read-items [request]

(let [items (map

#(assoc % :url (str "/item/" (:id %)))

(get-all-items db-spec))]

{:status 200

:body (html (item-list {:items items}))}))

Page 23: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD the data

({:id 1

:name “Test item”

:url “/item/1”

:quantity 5}

{:id 2

:name “Another item”

:url “/item/2”

:quantity 26}

{:id 3

:name “Item”

:url “/item/3”

:quantity 3})

Page 24: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD item list handler

(defn read-items [request]

(let [items (map

#(assoc % :url (str "/item/" (:id %)))

(get-all-items db-spec))]

{:status 200

:body (html (item-list {:items items}))}))

Page 25: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD the data

{:items ({:id 1

:name “Test item”

:url “/item/1”

:quantity 5}

{:id 2

:name “Another item”

:url “/item/2”

:quantity 26}

{:id 3

:name “Item”

:url “/item/3”

:quantity 3})

Page 26: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD item list handler

(defn read-items [request]

(let [items (map

#(assoc % :url (str "/item/" (:id %)))

(get-all-items db-spec))]

{:status 200

:body (html (item-list {:items items}))}))

Page 27: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD the data

[:div {}

[:h1 {} "Item List"]

[:table {:class “items”}

[:tr {}

[:td {:class “id”} 1]

[:td {:class “name”} “Test Item”]

[:td {:class “quantity”} 5]

[:td {}

[:form {:action “/item/1” :method “post”}

[:button {:type "submit“} "delete"]]]]]

...

Page 28: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD item list handler

(defn read-items [request]

(let [items (map

#(assoc % :url (str "/item/" (:id %)))

(get-all-items db-spec))]

{:status 200

:body (html (item-list {:items items}))}))

Page 29: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD the data

<div>

<h1>Item List</h1>

<table class=“items”>

<tr>

<td class=“id”> 1</td>

<td class=“name”>Test Item</td>

<td class=“quantity”>5</td>

<td>

<form action=“/item/1” method=“post”>

<button type="submit“>delete</button>

</form>

</td>

</tr>

...

Page 30: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD item list handler

(defn read-items [request]

(let [items (map

#(assoc % :url (str "/item/" (:id %)))

(get-all-items db-spec))]

{:status 200

:body (html (item-list {:items items}))}))

Page 31: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD test run!

$ lein ring server

Now open localhost:3001/items

Page 32: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD Erinite/template crash course

(def item-list-template

[:div

[:h1 "Item List"]

[:table.items

[:tr

[:td.id] [:td.name] [:td.quantity]

[:td [:form {:method “post”} [:button {:type "submit“} "delete"]]]]]

[:hr] [:div "New item"]

[:form#new {:action "/items“ :method "post"}

[:input.name {:type "text"}]

[:input.description {:type "text"}]

[:input.quantity {:type "text"}]

[:button {:type "submit"} "add"]]])

Page 33: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD Erinite/template crash course

(def item-list-template

[:div

[:h1 "Item List"]

[:table.items

[:tr

[:td.id] [:td.name] [:td.quantity]

[:td [:form {:method “post”} [:button {:type "submit“} "delete"]]]]]

[:hr] [:div "New item"]

[:form#new {:action "/items“ :method "post"}

[:input.name {:type "text"}]

[:input.description {:type "text"}]

[:input.quantity {:type "text"}]

[:button {:type "submit"} "add"]]])

[:.items] [:clone-for :items]

Page 34: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD Erinite/template crash course

(def item-list-template

[:div

[:h1 "Item List"]

[:table.items

[:tr

[:td.id] [:td.name] [:td.quantity]

[:td [:form {:method “post”} [:button {:type "submit“} "delete"]]]]]

[:hr] [:div "New item"]

[:form#new {:action "/items“ :method "post"}

[:input.name {:type "text"}]

[:input.description {:type "text"}]

[:input.quantity {:type "text"}]

[:button {:type "submit"} "add"]]])

[:.items] [:clone-for :items]

Page 35: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD Erinite/template crash course

(def item-list-template

[:div

[:h1 "Item List"]

[:table.items

[:tr

[:td.id] [:td.name] [:td.quantity]

[:td [:form {:method “post”} [:button {:type "submit"} "delete"]]]]]

[:hr] [:div "New item"]

[:form#new {:action "/items“ :method "post"}

[:input.name {:type "text"}]

[:input.description {:type "text"}]

[:input.quantity {:type "text"}]

[:button {:type "submit"} "add"]]])

[:.items] [:clone-for :items]

{:items ({:id 1

:name “Test item”

:url “/item/1”

:quantity 5}

{:id 2

:name “Another item”

:url “/item/2”

:quantity 26}

{:id 3

:name “Item”

:url “/item/3”

:quantity 3})

Page 36: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD Erinite/template crash course

(def item-list-template

[:div

[:h1 "Item List"]

[:table.items

[:tr

[:td.id] [:td.name] [:td.quantity]

[:td [:form {:method “post”} [:button {:type "submit“} "delete"]]]]]

[:hr] [:div "New item"]

[:form#new {:action "/items“ :method "post"}

[:input.name {:type "text"}]

[:input.description {:type "text"}]

[:input.quantity {:type "text"}]

[:button {:type "submit"} "add"]]])

[:.items :.id] [:content :id]

Page 37: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD Erinite/template crash course

(def item-list-template

[:div

[:h1 "Item List"]

[:table.items

[:tr

[:td.id] [:td.name] [:td.quantity]

[:td [:form {:method “post”} [:button {:type "submit“} "delete"]]]]]

[:hr] [:div "New item"]

[:form#new {:action "/items“ :method "post"}

[:input.name {:type "text"}]

[:input.description {:type "text"}]

[:input.quantity {:type "text"}]

[:button {:type "submit"} "add"]]])

[:.items :.id] [:content :id]

{:id 1

:name “Test item”

:url “/item/1”

:quantity 5}

Page 38: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD detour: erinite/template-stylesheets

Detour Time!

Erinite/template comes with a companion library: erinite/template-stylesheets

Page 39: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD detour: erinite/template-stylesheets

Detour Time!

Erinite/template comes with a companion library: erinite/template-stylesheets

{[:.items] [:clone-for :items][:.items :.id] [:content :id][:.items :.name] [:content :name][:.items :.quantity] [:content :quantity][:.items :form] [:set-attr :action :url]}

Page 40: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD detour: erinite/template-stylesheets

Detour Time!

Erinite/template comes with a companion library: erinite/template-stylesheets

{[:.items] [:clone-for :items][:.items :.id] [:content :id][:.items :.name] [:content :name][:.items :.quantity] [:content :quantity][:.items :form] [:set-attr :action :url]}

Page 41: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD detour: erinite/template-stylesheets

.items {clone-for: items;

}.items .id {

content: id;}.items .name {

content: name;}.items .quantity {

content: quantity;}.items form {

set-attr: action url;}

Page 42: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD detour: erinite/template-stylesheets

.items {clone-for: items;

}.items .id {

content: id;}.items .name {

content: name;}.items .quantity {

content: quantity;}.items form {

set-attr: action url;}

Now your designers can update yourtemplate transformation selectors!

Page 43: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD deleting items

-- name: delete-item!

-- Delete a specific item from the database.

DELETE FROM items

WHERE id = :id

Page 44: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD deleting items

(defn delete-item [request]

(let [item-id (get-in request

[:route-params :item-id])]

(delete-item! db-spec item-id)

{:status 302

:headers {"Location" "/items"}}))

Page 45: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD deleting items

(defn delete-item [request]

(let [item-id (get-in request

[:route-params :item-id])]

(delete-item! db-spec item-id)

{:status 302

:headers {"Location" "/items"}}))

Page 46: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD create our routes

(def routes

["/" {"items"

{{:request-method :get} read-items

{:request-method :post} create-item}

["item/" :item-id]

{{:request-method :get} read-item

{:request-method :put} update-item

{:request-method :post} delete-item

{:request-method :delete} delete-item}}])

Page 47: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD deleting items

(defn delete-item [request]

(let [item-id (get-in request

[:route-params :item-id])]

(delete-item! db-spec item-id)

{:status 302

:headers {"Location" "/items"}}))

Page 48: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD deleting items

(defn delete-item [request]

(let [item-id (get-in request

[:route-params :item-id])]

(delete-item! db-spec item-id)

{:status 302

:headers {"Location" "/items"}}))

Page 49: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

DIY CRUD

...and so on for create and update.

Page 50: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

Where to next?

Liberator

Define resources as conditions and actions in a state machine.

Very flexible

Makes it easy to be RFC compliant

But is lower level than I’d like

Page 51: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

Where to next?

Yada

JUXT’s new Liberator competitor

Simpler and higher level than Liberator

Built-in swagger support

Page 52: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

Where to next?

Erinite/crud

There is no good out-of-the-box CRUD library than I know of. So I plan on making one.

https://github.com/Erinite/crud

Page 53: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

Where to next?

Erinite/crud

Doesn’t exist yet, so I’m taking feature requests

Page 54: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

Where to next?

Erinite/crud

The plan so far:

• Support any database (by implementing a protocol)

• Data-driven handlers (you define your resources as data, library does the rest)

• Just a handler, so you can mount it at any route you want

Page 55: Building CRUD applications in Clojure - Meetupfiles.meetup.com/10978482/Building CRUD applications in Clojure.pdf · •Defacto standard. DIY CRUD •Request Handler ... Erinite/template

Questions?