Question

New to Clojure and wondering how to use it to make other languages I program in easier.

One thing I would like to be able to do is use Clojure for code generation.

For example, given the input from a data file (EDN format) how should I (1) walk this structure or (2) push the data into an existing templating mechanism?

Data below would be for defining simple REST API so that you could generate Clients from it. Generate clients in multiple languages by using different templates.

(:restcall "GetAccountBalance" 
  {:method "GET" :path "account/balance"}
  {:id int})

(:restcall "GetLastTransactions" 
  {:method "GET" :path "account/transactions"}
  {:page int})

resulting code would be something like

public void GetAccountBalance(int id) 
{
    var input = new { id = id };
    callIntoRestLibrary("GET", "account/balance", input);
}

public void GetLastTransactions(int page) 
{
    var input = new { page = page };
    callIntoRestLibrary("GET", "account/transactions", input);
}

Note: my end goal would having these as System.Net.Http.HttpClient calls via C#, but also be able to translate these into JavaScript/Ajax calls also

Was it helpful?

Solution

You have several choices for templating with Clojure. One place to look is the Clojure Toolbox.

Here is an example with clostache, a small library (358 loc) implementation of mustache.

(ns so.core
  (:require [clostache.parser :refer (render)]))

(def template "
public void {{restcall}}({{id}} id) 
{
    var input = new { id = id };
    callIntoRestLibrary(\"{{method}}\", \"{{path}}\", input);
}")

(def data 
  {:restcall "GetAccountBalance" 
   :method "GET" :path "account/balance" :id "int"})


(print (render template data))

Output:

public void GetAccountBalance(int id)
{
    var input = new { id = id };
    callIntoRestLibrary("GET", "account/balance", input);
}

To clear up confusion about what it means to read EDN.

(spit "foo.txt" (prn-str data))

Now the file foo.txt contains a textual representation of data, presumably your starting point.

(def data2 (with-open [r (java.io.PushbackReader. (java.io.FileReader. "foo.txt"))] 
             (clojure.edn/read r)))

(= data data2) ;=> true

So, read doesn't just pull in text, but also parses it into its data representation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top