├── README.md └── ob-graphql.el /README.md: -------------------------------------------------------------------------------- 1 | # ob-graphql 2 | > GraphQL execution backend for org-babel 3 | 4 | [![MELPA](https://melpa.org/packages/ob-graphql-badge.svg)](https://melpa.org/#/ob-graphql) 5 | 6 | This package provides an execution backend for org-babel source blocks that can execute GraphQL queries and display the results inline. 7 | 8 | ## Installation 9 | 10 | This project is available [on Melpa](https://melpa.org/#/ob-graphql). You can install it with `M-x package-install ob-graphql` or using the package management solution of your choice. Alternatively, you can put `ob-graphql.el` on your load path somewhere and load it via `(require 'ob-graphql)`. After that you'll be able to evaluate GraphQL code blocks. 11 | 12 | If you're installing `ob-graphql` manually you'll also need to install [`graphql-mode`](https://github.com/davazp/graphql-mode). 13 | 14 | ## Usage 15 | 16 | The URL of the GraphQL server should be given by the `:url` header parameter: 17 | 18 | ``` org 19 | #+BEGIN_SRC graphql :url https://countries.trevorblades.com/ 20 | query GetContinents { 21 | continent(code: "AF") { 22 | name 23 | code 24 | } 25 | } 26 | #+END_SRC 27 | 28 | #+RESULTS: 29 | : { 30 | : "data": { 31 | : "continent": { 32 | : "name": "Africa", 33 | : "code": "AF" 34 | : } 35 | : } 36 | : } 37 | ``` 38 | 39 | Variables can be passed into the source block from other source/example blocks via the `:variables` header parameter. The parameter should be the name of the variables source block, which should evaluate to the JSON body of the variables to pass into the query: 40 | 41 | ``` org 42 | #+NAME: my-variables 43 | #+begin_example 44 | { 45 | "continentCode": "AF" 46 | } 47 | #+end_example 48 | 49 | #+BEGIN_SRC graphql :url https://countries.trevorblades.com/ :variables my-variables 50 | query GetContinents($continentCode: String!) { 51 | continent(code: $continentCode) { 52 | name 53 | code 54 | } 55 | } 56 | #+END_SRC 57 | 58 | #+RESULTS: 59 | : { 60 | : "data": { 61 | : "continent": { 62 | : "name": "Africa", 63 | : "code": "AF" 64 | : } 65 | : } 66 | : } 67 | ``` 68 | 69 | Additional headers, such as an `Authorization` header, can be passed into the query via the `:headers` header parameter. This parameter should be the name of another source block that evaluates to an alist of header names to header values: 70 | 71 | ``` org 72 | #+NAME: my-headers 73 | #+BEGIN_SRC emacs-lisp 74 | '(("Authorization" . "Bearer my-secret-token")) 75 | #+END_SRC 76 | 77 | #+BEGIN_SRC graphql :url https://countries.trevorblades.com/ :headers my-headers 78 | query GetContinents { 79 | continent(code: "AF") { 80 | name 81 | code 82 | } 83 | } 84 | #+END_SRC 85 | 86 | #+RESULTS: 87 | : { 88 | : "data": { 89 | : "continent": { 90 | : "name": "Africa", 91 | : "code": "AF" 92 | : } 93 | : } 94 | : } 95 | ``` 96 | -------------------------------------------------------------------------------- /ob-graphql.el: -------------------------------------------------------------------------------- 1 | ;;; ob-graphql.el --- Org-Babel execution backend for GraphQL source blocks -*- lexical-binding: t; -*- 2 | 3 | ;; Copyright (C) 2019 Jeremy Dormitzer 4 | 5 | ;; Author: Jeremy Dormitzer 6 | ;; Version: 1.1 7 | ;; Package-Requires: ((emacs "24.4") (graphql-mode "20191024.1221") (request "0.3.2")) 8 | ;; URL: https://github.com/jdormit/ob-graphql 9 | 10 | ;; This program is free software; you can redistribute it and/or modify 11 | ;; it under the terms of the GNU General Public License as published by 12 | ;; the Free Software Foundation, either version 3 of the License, or 13 | ;; (at your option) any later version. 14 | 15 | ;; This program is distributed in the hope that it will be useful, 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | ;; GNU General Public License for more details. 19 | 20 | ;; You should have received a copy of the GNU General Public License 21 | ;; along with this program. If not, see . 22 | 23 | ;;; Commentary: 24 | 25 | ;; This package provides an org-babel execution backend for GraphQL code blocks. 26 | 27 | ;;; Code: 28 | (require 'ob) 29 | (require 'ob-ref) 30 | (require 'graphql-mode) 31 | (require 'json) 32 | (require 'request) 33 | 34 | (add-to-list 'org-babel-tangle-lang-exts '("graphql" . "gql")) 35 | 36 | (defconst org-babel-header-args:graphql 37 | '((:url . :any) 38 | (:variables . :any) 39 | (:headers . :any)) 40 | "GraphQL-specific header arguments") 41 | 42 | ;;;###autoload 43 | (defun org-babel-execute:graphql (body params) 44 | "Executes Org-Babel src block BODY with headers parameters PARAMS. 45 | 46 | Called by `org-babel-execute-src-block' on source blocks declared 47 | as type \"graphql.\"" 48 | (let* ((url (cdr (assq :url params))) 49 | (url (if (org-file-url-p url) 50 | url 51 | (org-babel-ref-resolve url))) 52 | (op-name (cdr (assq :operation params))) 53 | (variables (cdr (assq :variables params))) 54 | (variables-val (when variables 55 | (json-read-from-string (org-babel-ref-resolve variables)))) 56 | (headers (cdr (assq :headers params))) 57 | (graphql-extra-headers 58 | (when headers (org-babel-ref-resolve headers))) 59 | (response (if variables-val 60 | (graphql-post-request url body op-name variables-val) 61 | (graphql-post-request url body op-name)))) 62 | (with-temp-buffer 63 | (insert (json-encode (request-response-data response))) 64 | (json-pretty-print-buffer) 65 | (buffer-substring (point-min) (point-max))))) 66 | 67 | (provide 'ob-graphql) 68 | ;;; ob-graphql.el ends here 69 | --------------------------------------------------------------------------------