Skip to content
This repository has been archived by the owner on Aug 27, 2019. It is now read-only.

Latest commit

 

History

History
121 lines (102 loc) · 5.5 KB

OLD_README.md

File metadata and controls

121 lines (102 loc) · 5.5 KB

ringfinger Build Status Maintained Status Flattr this git repo

A collection of modern web application libraries for Clojure/Ring.
Designed for the age of NoSQL, HTML5, REST, JSON, VPS, (sadly) CSRF, XSS and other acronyms.
Modular. Simple. Fast. Secure. Named after a great Nine Inch Nails song.

Check out the website for a live demo. Also, there are API docs and the wiki.

Get excited

(ns webapp.core
  (:use corefinger.core,
        restfinger.core,
        formfinger.fields,
        (authfinger core routes),
        (basefinger core inmem mongodb session),
        fastfinger.hooks,
        ring.util.serve))

(def database
  (if-env "production" (mongodb "mydb") inmem)

(defresource contacts
  {:db database 
   :pk :name_slug
   :hooks {:data (make-slug-for :name)}}
  [:name  (required)    "sorry, anonymous"]
  [:bday  (date-field)  "invalid date"]
  [:email (email-field) "invalid email"])

(defapp myapp
  {:session-store (db-store database)
   :middleware #(-> % (wrap-auth {:db database}))}
  contacts
  (auth-routes {:db database}))

(serve myapp 8080)

or something like that. You can do create/read/update/delete operations on the same resource with a browser (there are default HTML templates, like in Rails) or something that supports JSON, YAML, CSV or XML. Yeah, URLs are the same. The app is an API, and HTML is just another output format. The Accept HTTP header (or adding .format to the URL) is what "separates" the API. And insert some example data by visiting /contacts/_create_fakes (only in development environment, of course). Nice, eh?

You can customize the behavior via hooks (eg. if you need to automatically add URL-friendly "slugs", as in the example, or automatic timestamps), via providing Lamina channels and subscribing to them (eg. if you need real-time push), adding custom actions (eg. for voting in a poll) or adding middleware.

You also can use lower-level auth/database/validation/output/routing APIs if you can't fit something into these RESTful constraints. Restfinger is just a module.

You can nest Ring handlers in apps. Or use "extended Ring handlers", "Ringfinger handlers", "Ring+Clout handlers", whatever you call them. With or without method dispatching.

(ns oldschool.app
  (:use corefinger.core, ring.util.serve))

(defapp helloapp {}
  (route "/rf/:name"
    ; just giving a map here is a shortcut
    ; to using method-dispatch-handler 
    {:get (fn [req matches]
            {:status 200
             :headers {"Content-Type" "text/plain"}
             :body (str "Hello, " (:name matches))})})
  (route "/oldapp/"
    (nest (fn [req]
            {:status 200
             :headers {"Content-Type" "text/plain"}
             :body "Hello old world"}))))

(serve helloapp 8080)

Get Involved

There are no long contributor agreements or whatever. It's simple:

  • If you contribute, you don't tell me to remove it later or whatever.
  • Use GitHub pull requests. You can start one before completing your work!

Get Waiting

aka, TODO list

Really Important Features

  • authfinger: invites, password recovery
  • read-only mode
  • rate limiting (per user)
  • queries in url prefixes (eg. :username prefix to allow :username/collname/:pk with the same pk values)
  • pagination html helper
  • file attachments w/ GridFS support
  • asset system that supports preprocessors, css sprite making & completely dynamic in dev mode & uploads to clouds for production with a lein task, using attachment storages. kinda like rails 3.1
  • optionally separating create/index and view/edit pages in html - possible to create "create" and "edit" pages manually now, but it should be easy
  • lein template

Someday

  • middleware like django-paranoid-sessions
  • HTML email support
  • OpenID, BrowserID, OAuth
  • atom feeds for resources
  • i18n
  • Sitemap and Swagger implementation
  • lazy signup
  • automatic javascript model definitions for client-side mvc per resource, using clojurescript
  • fastfinger.subscribers: Pusher, Superfeedr (after adding atom feeds), webhook
  • fastfinger.actions for polls (change -1/0/+1 per user, like reddit), voting (like votebox)
  • FleetDB, CouchDB support
  • cloudy packages (ringfinger-aws = S3 + SES + SimpleDB, ringfinger-gae = Blobstore + Mail + Datastore)
  • database and attachment migrations (eg. mongodb + gridfs to simpledb + s3)
  • easy full text search (elasticsearch, lucene): lamina subscriber + route for querying
  • (fun!) external package for outputting data in native formats - python pickle using jython, php serialized array using quercus. or even implement them in clojure