Verb is a capable mode for Emacs and Org mode that allows to define and perform HTTP calls. Besides offering many useful features on its own, it also provides multiple ways how to extends its capabilities. Thanks to them, it can be easily turned into GraphQL client.
Key to this is property Verb-Map-Request
. This property can hold a function that modifies HTTP request.
The function receives object of verb-request-spec class and returns this object modified.
In order to turn a bare GraphQL query into HTTP request, it has to be put, as a string, into JSON object under
the key query
. Variables for the query can be attached to this object under key variables
. This can be achieved
by this request-mapping function:
(defun verb-graphql (rs)
"Converts Verb-mode's request object RS into a GraphQL request.
For use with Verb-Map-Request property."
(pcase-let* ((`(,query ,variables) (split-string (oref rs body) ":variables:"))
(body `(:query ,query :variables ,(json-parse-string variables))))
(oset rs body (json-encode body)))
rs)
In the following Org file, Verb-Map-Request
is set to verb-graphql
. The string :variables:
serves as
a separator of the main request and variables. Perhaps there are better ways how to pass variables
to the mapping function. org-use-property-inheritance
has to be set to t
so that the
Verb-Map-Request
property is visible in whole subtree.
C-c C-c
in the source block will make the GraphQL call. Any other Verb functions, e. g.
verb-export-request-on-point-curl
still work as expected.
* Github GraphQL API :verb:
:properties:
:Verb-Map-Request: verb-graphql
:end:
TEMPLATE https://api.github.com/graphql
User-Agent: emacs-test
Authorization: Bearer {{(shell-command-to-string "gh auth token")}}
** Get Pull Requests
POST
#+begin_src graphql
query GetPullRequests($owner: String!, $name: String!) {
repository(owner: $owner, name: $name) {
pullRequests(first: 10, after: null) {
nodes {
createdAt
number
title
}
pageInfo {
endCursor
startCursor
hasNextPage
hasPreviousPage
}
}
}
}
:variables:
{
"owner": "rust-bitcoin",
"name": "rust-bitcoin"
}
#+end_src
* Variables
# Local Variables:
# org-use-property-inheritance: t
# eval: (verb-mode)
# End:
References Link to heading
Heavily inspired by u/rontan who shared this idea in a Reddit comment. Thanks!