A wiki made with Clojure, yada and Datomic Client
04 Jan 2017At EuroClojure in Bratislava an unconference session was about
Clojure and REST. At this
session Liberator
and yada were discussed by their
authors. I have used Liberator previously, by not yada. A big
difference between the two is that yada is asynchronous. This is
useful when making calls to other services while handling a web
request.
Datomic now has a new Client
API. With the Client API a Datomic database can be accessed as a
service, in a more idiomatic Clojure style than its old REST API. To
play around with yada and Datomic Client I made a wiki with it. As a
bonus the example yada project also
uses Boot, instead of Leiningen as
its build tool,
which I had not played around with either.
The code for clj-wiki is on
GitHub: https://github.com/thegeez/clj-wiki
An example wiki is (temporarily) running at http://wiki.thegeez.net
Libraries
- yada an async and full http Clojure web library
- Edge a yada example web app, including configuration etc.
- Datomic Client a new API to use with Datomic
- SimpleMDE a Markdown editor component
- google-diff-match-patch for diffs and patches
Structure
In a wiki everybody can make changes to articles and add new articles. In clj-wiki all the edits to an article are stored as a transaction in Datomic. The comment on an edit is saved as an attribute on the transaction. The actual content of an article at a particular version is stored as a plain text file in a storage server and a reference to it is stored in Datomic. Yada has good support for handling file uploads and downloads. Having both Datomic and the fileserver as a service shows the usefullness of yada being asynchronous when doing multiple requests to external services while handling web requests.
The interesting code in the clj-wiki project is in wiki.clj
Conflict handling
The difficult part in a wiki is what to do when multiple users try to change the same article at the same time. In clj-wiki these situations are detected and when they happen users are shown a conflict page where they have to incorporate any changes made by other users. No edits are ever silently overwritten or discarded.
A screen to resolve editing conflicts, showing the differences.
The code is on GitHub: https://github.com/thegeez/clj-wiki