restclient.el
restclient.el copied to clipboard
Bind response to a variable?
Especially, I'd like to POST .../login
and parse out an auth token, which following endpoints require.
There's a way to do this with org-babel
and ob-restclient
, but that whole setup is a bit verbose, and not nearly as fun as just restclient
.
PS, I have Postman PTSD, and I since I just discovered restclient
I can begin to recover. Thank you!
Just leavin this here for anyone who might benefit, but a better option would still be appreciated:
I came up with this hack of a solution. It uses elisp to do the query instead of restclient, and then parses the header+body string into the token I want with some terrible, abysmal, abominable, evil, yet somehow elisp-appropriate hack.
:jwt := <<
(let ((url-request-method "POST")
(url-request-extra-headers '(("Content-Type" . "application/json")))
(url-request-data (json-encode '(("email" . "a") ("clearPass" . "a")))))
(with-current-buffer (url-retrieve-synchronously "http://localhost:8081/token")
(goto-char (point-min))
(re-search-forward "\\\"")
(delete-region (point) (point-min))
(goto-char (point-max))
(backward-char 1)
(delete-region (point) (point-max))
(buffer-string)))
#
@freckletonj I think of advising the restclient-http-parse-current-and-do
to wrap the callback function func
to persist the arguments for the current request would suffice.
Either way, this feature would be nice to have.
Being able to do this would turn this tool from a great tool to a quintessential tool for me :)
I ended up with the following:
(defvar my-restclient-token nil)
(defun my-restclient-hook ()
"Update token from a request."
(save-excursion
(save-match-data
;; update regexp to extract required data
(when (re-search-forward "\"token\":\"\\(.*?\\)\"" nil t)
(setq my-restclient-token (match-string 1))))))
(add-hook 'restclient-response-received-hook #'my-restclient-hook)
and then in restclient
:token := my-restclient-token
...
GET http://127.0.0.1:3000/api/clients/
authorization: Token :token
So when you need to update a token you run your auth request
POST http://127.0.0.1:3000/api/users/login
Content-Type: application/json
{"user": {"login": "tester", "password": "qwerty"}}
and hook will extract the token for you, thus you can use it in your next requests.
@pashky I think this feature is what a lot of users want, do you think this solution is good enough to be mentioned on the readme?
Is it possible to add conditional hooks? In my case, I have a consumer
and user
tokens that I need to retrieve from multiple URLs.
I know very basic elisp, if it's easy I can do a small PR for this.
No, but the url is available in the hooks. You can switch actions based upon the url...
(require 'restclient)
(require 'json)
(defvar my-restclient-token nil)
(defun my-restclient-hook ()
"Update token from a request."
;; url is visible while the hook is running.
(let ((result))
(save-excursion
(cond
((string-suffix-p "/token" url)
(condition-case nil
(progn
(setq result (cdr (assoc 'token (json-read)))
(when (stringp result)
(progn
(setq my-restclient-token result)
(message (concat "stored token: " my-restclient-token)))))
(error (message "That wasn't cleanly handled."))))))))
(add-hook 'restclient-response-loaded-hook #'my-restclient-hook)
(provide 'restclient-hooks)
(The above assumes the response is json.)