Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making JSON requests within Emacs

I am in the early stages of writing an Emacs major mode for browsing and contributing to sites on the Stack Exchange network, in much the same way as dired and list-packages works, with a few inspirations from magit and org-mode.

The problem is, of course, I have no idea how I would interface Emacs with the SE API (v2.1) in the first place. I've never done anything that involves a network connection within Elisp, although I'm comfortable with the language itself (and have taken more than a few looks at package.el).

I've never worked with JSON, although I'm in the middle of W3C's tutorial on it.

A simple 'hello world' would suffice, possibly along the lines of

(execute-json-query "/info")

The W3C tutorial doesn't seem to go over requests, either. I'll have to do my own research on that.
I really don't have any idea what I'm doing; I've only just started feverishly working on this yesterday afternoon.

like image 906
Sean Allred Avatar asked Feb 27 '13 17:02

Sean Allred


3 Answers

The problem with other answers is that Stack Exchange API is GZIP'd and url.el shipped with Emacs does not automatically decompress it.

Take a look at my request.el library which supports automatic decompression (to be honest, I just added the support). Here is an example to fetch the most active question in stackoverflow:

(request
 "https://api.stackexchange.com/2.1/questions"
 :params '((order . "desc")
           (sort . "activity")
           (site . "stackoverflow"))
 :parser 'json-read
 :success (function*
           (lambda (&key data &allow-other-keys)
             (let* ((item (elt (assoc-default 'items data) 0))
                    (title (assoc-default 'title item))
                    (tags (assoc-default 'tags item)))
               (message "%s %S" title tags)))))

request.el is well documented, comes with executable examples and is well tested.

like image 162
tkf Avatar answered Oct 15 '22 18:10

tkf


Take a look at REST Client on GitHub - a tool to manually explore and test HTTP REST webservices.

like image 11
David J. Liszewski Avatar answered Oct 15 '22 19:10

David J. Liszewski


This may not be the best way of doing things but it seems to work for me.

(defun fetch-json (url)
   (with-current-buffer (url-retrieve-synchronously url)
     ; there's probably a better way of stripping the headers
     (search-forward "\n\n")
     (delete-region (point-min) (point))
     (buffer-string)))

Then calling this function with a url will return the content of the response, in this case, json. I've used the reddit api as an example because I'm not sure how the Stack Exchange api works.

 (fetch-json "http://reddit.com/r/emacs.json")

There is pretty much no error checking included here, if the url returns no data then this will blow up.

like image 8
Randy Morris Avatar answered Oct 15 '22 19:10

Randy Morris