liberator
Liberator is a Clojure library for building RESTful applications.
Liberator - Welcome
I am trying to get my head round clojure liberator and i have come across this type of code below:
:handle-ok (by-method {
:get (fn [ctx] (render-item (:item ctx)))
:post (fn [ctx] (render-item (:item ctx)))
:put (fn [ctx] (update-item-response coll-slug ctx))})
At first I thought that handle-ok
was simply for GET requests but then I came across this.
Why would I provide handlers for post and put in the example above? Are these post-request handlers.
Source: (StackOverflow)
I'm using liberator with compojure, and wanted to send multiple methods (but not all methods) to the save resource. Rather than repeating myself, I'd like to have something that defines multiple handlers at once.
An example:
(defroutes abc
(GET "/x" [] my-func)
(HEAD "/x" [] my-func)
(OPTIONS "/x" [] my-func))
Should be closer to:
(defroutes abc
(GET-HEAD-OPTIONS "/x" [] my-func))
Source: (StackOverflow)
How to return json-data with Clojure Liberator? This code doesn't work:
(defresource poster []
:allowed-methods [:post :options]
:available-media-types ["application/json"]
:post! (fn [ctx] (println "posting..."))
:handle-created (fn [ctx] {:created "ok"}))
Should handle-created be called after post?
Source: (StackOverflow)
I'm fairly new to clojure/compojure, but really love it. Naturally, started my exploration with Noir stack. Have written a POC app. Then, discovered Liberator -- makes a whole lot of sense. Just wondering, if anybody has ever migrated Noir applications to Liberator before. Any references to articles/blogs that cover this would be highly appreciated.
Source: (StackOverflow)
I have such a code:
(defresource errors []
:authorized? (fn [ctx] (authorized? ctx))
:allowed-methods [:post :options]
:available-media-types media-types
:post! (fn [ctx] (-> ctx
parse-json
errors/insert-error)))
authorized? function checks user token, but I have some other rules, which I want to check inside post! function. How to do it? I can throw an Exception from the post! function, but I would like to return 401 status code.
Source: (StackOverflow)
I'm writing clojure rest service (with ring, compojure and liberator) and would like to automatically generate API documentation for all my REST API. It's very tedious to generate it manually. Is there any way to use annotations or something like this? It will be cool if I can do it with lein gen-rest-docs.
Source: (StackOverflow)
I have a problem with liberator body-as-string function and line-seq.
(println
(line-seq
(BufferedReader. (StringReader. (body-as-string ctx)))
)
)
With this curl command the function return (h1,h2\nh3,h4\nh5,h6)
instead of (h1,h2 h3,h4 h5,h6)
curl "localhost:3000/log" -X POST -H "Content-type:text/csv" -d "h1,h2\nh3,h4\nh5,h6"
EDIT :
I add body-as-string function :
(defn body-as-string
"Parcours le contexte de la requĂȘte pour en extraire le body"
[ctx]
(timbre/debug "body-as-string")
(if-let
[body (get-in ctx [:request :body])]
(condp instance? body
java.lang.String body
(slurp (io/reader body))
)
)
)
Maybe is it an encoding problem ?
Thank you !
Source: (StackOverflow)
Let's assume, that I've got an endpoint POST /endpoint
that takes JSON as input data:
POST /endpoint
{
"resource": {
"name": "great"
}
}
Now, I want to check whether the incoming JSON is valid. I thought that :malformed?
hook would be a great place for doing that.
So I came up with such a code:
(ANY "/endpoint" []
(resource
:allowed-methods [:post]
:available-media-types ["application/json"]
:malformed? (fn [ctx] (let [body (get-body-from-request ctx)
is-malformed (not (is-body-valid body))]
is-malformed)
:post! (fn [ctx] (let [body (get-body-from-request ctx)]
(create-an-object body)))
:handle-created (fn [ctx] {:method :post :body (:body @request)})))
So my intention was:
- get the
body
from request, check if it's valid (is-body-valid
)
- in
post!
hook, use the body
again and do real work (create-an-object
)
The problem here is the get-body-from-request
function:
(defn get-body-from-request [ctx]
(json/read-str (slurp (get-in ctx [:request :body])) :key-fn keyword))
It works perfectly but the body
is an InputStream
, so I can read it only once.
Is there a way to use body
of the request in more than one hook NOT using atoms?
The solutions coming to my mind:
- A middleware wrapper that adds a string version of
body
to the ctx
param.
- Pass the result of
malformed?
to post!
...
- Use atoms.
Thanks!
Source: (StackOverflow)
I wanted to use a decision point :media-type-available?
but I failed...
I know I have to set the :representation :media-type
but I don't really know how to do it.
So far, my code looks as the following:
(defresource test-resource []
:media-type-available (fn [req]
(assoc req :representation {:media-type "application/json"}))
:available-media-types ["application/json" "text/html"]
:handle-ok (fn [req] {:ok true})
)
Remarks:
(assoc req :representation {:media-type "application/json"})
produces a correct map with "changed" req
object.
- in
:handle-ok
's req
object, the :representation
value is {}
I have no idea how to set it (it's not a mutable object, is it?) and looking at the liberator's source code doesn't really help...
Thanks,
Karol
Source: (StackOverflow)
Where in the Liberator decision tree should I validate form input?
:malformed?
seems to aimed at detecting invalid JSON or invalid form bodies.
Source: (StackOverflow)
I write a REST API with Clojure liberator, and I have this function, in order to build the URL:
(defn build-entry-url [request]
(URL. (format "%s://%s:%s%s"
(name (:scheme request))
(:server-name request)
(:server-port request)
(:context request))))
Then I use halresource for representing resources and cheshire to parse the json. When I use curl
, in json response the URL is showed as:
http:\/\/localhost:8080\/api\/customer\/1
But if I use some tool, like Postman, the URL is showed correctly
Any suggestion?
UPDATE: I re-checked and all json is generated correctly, but when I use curl, or trying access the end-point via browser, the URL is showed as: http:\/\/localhost:8080\/api\/customer\/1
Source: (StackOverflow)
I'm trying to build a simple rest api, using liberator and monger :
(ns tm.place.endpoint
(:require [liberator.core :refer [defresource]]
[monger [collection :as mc] [query :as mq]]
[clojure.data [json :as json]]
monger.json))
(defresource entity-place-resource [id]
:available-media-types ["application/json"]
:allowed-methods [:get :put :delete]
:exists? (if-let [place (mc/find-map-by-id "place" id)] {:place place})
:handle-ok :place
; :handle-created (fn [ctx]
; (let [body (-> ctx :request :body)]
; (assoc body :_id id)))
:handle-not-found []
:handle-not-acceptable "Should accept application/json"
:handle-method-not-allowed (json/write-str
{:message "Can only handle get, put and delete"})
; :handle-not-implemented
; :handle-no-content
:put! (fn [ctx]
(let [body (-> ctx :request :body)]
(mc/update-by-id "place" id (assoc body :_id id))))
:delete! (mc/remove-by-id "place" id)
:can-put-to-missing? false)
I'm using advanced rest client
to see if it works. If the method is :get
or :delete
, it does perfectly what I want (It first check if a document is exists, and then do the appropriate action). However, if the method is :put
, it simply spits out http 201 created, which I think the request is success, but the corresponding document is deleted, not updated.
If I comment out the :delete! line, the :put! is work as expected, so I'm guessing the culprit is the :delete!
line, but I have no idea why because since I'm using :put
method, I'm assuming :delete! should remain untouched. Any idea why?
Source: (StackOverflow)
I am using liberator to build a API using Clojure. Given the follow code:
(defresource single-customer [id]
:allowed-methods [:get, :put]
:exists? (fn [_]
(let [e (get @cust/customers (keyword id))]
(if-not (nil? e)
{::entry e})))
:existed? (fn [_] (nil? (get @cust/customers (keyword id) ::sentinel)))
:available-media-types ["application/json"]
:can-put-to-missing? false
:put! (fn [q] (cust/set-as-fraudulent id))
:handle-ok ::entry)
Someone when can tell me if is possible, like the GET request, when I send a PUT request it be redirected to the resource ? "/customer/1"
(for example) ?
Source: (StackOverflow)
I'm using Liberator, and am having a hard time getting my POSTed data into a map using with keywords as the keys. Here is my resource, with a few printlines for testing:
(defresource finish_validation
:allowed-methods [:post]
:available-media-types ["application/json"]
:post! (fn [context]
(let [params (slurp (get-in context [:request :body]))
mapped_params (cheshire/parse-string params)]
(println (type params))
(println (type mapped_params))
(validation/finish mapped_params)))
:handle-created (println ))
For testing, I'm posting the data using curl:
curl -H "Content-Type: application/json" -X POST -d '{"email":"test@foo.com","code":"xyz"}' http://localhost:8080/validate
cheshire converts the params into a map, but the keys are not keywords: I get {email test@foo.com, code xyz}
as the output, instead of the hoped-for {:email test@foo.com, :code xyz}
.
Should I be doing something differently? Is this even the right approach to getting the data?
Source: (StackOverflow)