Reputation: 2177
I have compojure based app where I need to parse a request and retrieve parameters that can be numbers. I want to be able to verify that the parameters exist and that they are numbers before actually processing the request. This is what I have so far:
(defn get-int [str]
"Returns nil if str is not a number"
(try (Integer/parseInt str)
(catch NumberFormatException _)))
(defn some-request [request]
(let [some-number (get-int (get-in request [:route-params :some-number])
other-number (get-int (get-in request [:route-params :other-number])]
(if (every? identity [some-number other-number])
(process-the-request)
(bad-request "The request was malformed")))
Is there a better way to do string -> number conversion?
Is there a better way to do request validation?
Upvotes: 7
Views: 2204
Reputation: 854
Use Long/parseLong
instead of Integer/parseInteger
. The latter supports only 32 bits, which is often insufficient; for instance, Datomic entity IDs don't fit into Integer.
Never use read-string
for user input. In addition, you must sanitize user input, removing injected scripts and such. https://github.com/alxlit/autoclave is a good start, although the defaults are arguably too aggressive.
Upvotes: 0
Reputation: 8996
This question contains good examples for parsing numbers in Clojure. If you are not sure that the string contains a valid number, your approach looks good.
If you can pass the parameters as part of the query string, you could use a route with regex to retrieve the value, e.g.
(GET ["/user/:id", :id #"[0-9]+"] [id]
(let [num (read-string id)]
(str "The number is: " num)))
The route would only match if the regex conditions are met, therefore you could skip the Integer/parseInt check.
Upvotes: 7