Search code examples
jsonrequestelisp

How to use request.el to communicate with local server


I am trying to use the request.el package to post data to a local server listening on port 8765 but I am having no success---I always get a null response. I wonder if I am doing something wrong with the port number---I didn't see any related examples in request.el's documentation. Or perhaps I am not using the right syntax for the json data the server expect. Here are the details:

I have a local server running on my local machine and listening on port 8765. It accepts json objects indicating which action it should execute. For instance, I can use curl to get the server's version number as follows:

curl localhost:8765 -X POST -d "{\"action\":\"version\", \"version\":6}"

The server's response is:

{"result": 6, "error": null}

My curl-equivalent request.el function is:

(request
     "http://127.0.0.1:8765"
     :type "POST"
     :data '(("action" . "version") ("version" . 6))
     :parser 'buffer-string               
     :complete (cl-function
                (lambda (&key response &allow-other-keys)
                  (message "Response is: %S" (request-response-data response)))))

I am expecting to get back the same JSON object curl returns, instead I get null:

Response is: "null"

In other words, the server seems not to understand the request. I am wondering what I am doing wrong?


Solution

  • You're currently POSTing data in the default format, which is a query string:

    action=version&version=6
    

    but you should be POSTing JSON data:

    {"action":"version","version":6}
    

    Change your :data specification to use JSON encoding:

    :data (json-encode '(("action" . "version") ("version" . 6)))