I am using Steel Bank Common Lisp (SBCL), Emacs, and Slime.
After executing a function, I have:
CL-USER> (my-function my-data)
"{\"key-1\": \"value-1\"}"
I would like to convert the string "{\"key-1\": \"value-1\"}"
to a REST request notation on curl, so a string as: key-1&value-1
Examplifying the application, this is going to be the data
on curl:
curl --request POST --data "userId=key-1&value-1" https://jsonplaceholder.typicode.com/posts
The solution is:
(ql:quickload :yason)
(defun json-string-to-rest-request (json-string)
(destructuring-bind (a b) (alexandria:hash-table-plist (yason:parse json-string))
(format nil "~a&~a" a b)))
You can apply it by:
(defparameter *json-string* "{\"key-1\": \"value-1\"}")
(defparameter *json-string-1* "{\"KeY-1\": \"value-1\"}")
(json-string-to-rest-request *json-string*)
;; => "key-1&value-1"
(json-string-to-rest-request *json-string-1*)
;; => "KeY-1&value-1"
Before this, I tried:
(ql:quickload :cl-json)
(defun json-string-to-rest (json-string)
(with-input-from-string (s json-string)
(destructuring-bind ((a . b)) (cl-json:decode-json s)
(format nil "~a&~a" (string-downcase a) b))))
(json-string-to-rest *json-string*)
;; => "key-1&value-1"
However, the downside is that cl-json:decode-json
transforms the json string first to ((:KEY-1 . "value-1"))
- so case sensistivity gets lost in the json key string when using cl-json
.
The package yason
reads-in the keys as strings and therefore preserves case-sensitivity in the key string.