|
|
|
|
|
by weavejester
5313 days ago
|
|
Sure thing. So superficially, Compojure and Sinatra look similar: get "/greet/:name" do |name|
"Hello #{name}"
end
(GET "/greet/:name" [name]
(str "Hello " name))
But these snippets of code are actually pretty different in what they do.The Sinatra code generates a new route and adds it to an instance variable on the current object: it's a side-effectful method. The Compojure code returns an anonymous function; it has no inherent side effects. If we wanted to do anything with it we'd want to bind it to a symbol: (def greeting
(GET "/greet/:name" [name]
(str "Hello " name)))
The other main difference is that Compojure has no implicit variables like "params" or "request". For instance, in Sinatra we could rewrite the example as: get "/greet/:name" do
"Hello #{params[:name]}"
end
But in Compojure, you don't get access to any variable you haven't explicitly bound: (GET "/greet/:name" {params :params}
(str "Hello " (params :name)))
So Compojure is effectively very explicit where Sinatra is implicit.The advantage of this approach is that Compojure is (IMO at least) better at nesting and abstracting functionality. For example: (context "/user/:id" [id]
(let [user (find-user id)]
(routes
(GET "/history"
(get-history user))
(GET "/profile"
(get-profile user)))))
|
|