Less reading more coding.
All code for this exercise is available here.
lein new compojure api-test
This sets up api-test
with a basic compojure template.
;; project.clj
...
:dependencies [[org.clojure/clojure "1.6.0"]
[ring/ring-json "0.3.1"]
[compojure "1.1.8"]]
Make sure stuffs there
lein deps
or install deps and run server at the same time:
lein ring server
Change your app definition to include the required middleware (make sure you require the middleware as well):
(ns api-test.handler
(:require [compojure.core :refer :all]
[compojure.handler :as handler]
[ring.middleware.json :as middleware]
[compojure.route :as route]))
;; ...
(def app
(-> (handler/site app-routes)
(middleware/wrap-json-body {:keywords? true})
middleware/wrap-json-response))
The {:keywords? true}
above makes sure that when my body is parsed, I get my keys as keywords and not as strings.
You get two things out of doing all this so far:
- All json request bodies are parsed into nice looking maps for your convinience.
- Response bodies can now be maps as well, which will be converted into JSON before they're put on the wire.
Lets write the handler (just look at the POST "/"
stuff):
(defroutes app-routes
(POST "/" request
(let [name (or (get-in request [:params :name])
(get-in request [:body :name])
"John Doe")]
{:status 200
:body {:name name
:desc (str "The name you sent to me was " name)}}))
(route/resources "/")
(route/not-found "Not Found"))
First it figures the name of the sender, it could be either in params
, the body
or defaults to "John Doe"
(see how nicely you can query the body here for things).
;; ...
{:status 200
:body {:name name
:desc (str "The name you sent to me was " name)}}
This is how you generate your body now, just a simple clojure map.
Lets check it out in console:
$ curl -X POST http://localhost:3000/ \
--data '{"name":"verma"}' --header "Content-type:application/json"
{"name":"verma","desc":"The name you sent to me was verma"}
$ curl -X POST --data 'name=verma' http://localhost:3000/
{"name":"verma","desc":"The name you sent to me was verma"}
$ curl -X POST http://localhost:3000/
{"name":"John Doe","desc":"The name you sent to me was John Doe"}
Until next time!