A wiki made with Clojure, yada and Datomic Client

04 Jan 2017

At 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