# GraphQL.el GraphQL.el provides a set of generic functions for interacting with GraphQL web services. See also the following resources: - [GraphQL language service][graph-lsp] and [`lsp-mode`][el-lsp] - [`graphql-mode`][graphql-mode] - [This brief overview of GraphQL syntax][graphql] [graph-lsp]: https://github.com/graphql/graphql-language-service [el-lsp]: https://github.com/emacs-lsp/lsp-mode [graphql-mode]: https://github.com/davazp/graphql-mode [graphql]: http://graphql.org/learn ## Syntax Overview Two macros are provided to express GraphQL *queries* and *mutations*: - `graphql-query` encodes the graph provided under a root `(query ...)` node. - `graphql-mutation` encodes the graph provided under a root `(mutation ...)` node. Both macros allow special syntax for query/mutation parameters if this is desired; see the docstrings for details. I will note that backtick notation usually feels more natural in Lisp code. ### Basic Queries The body of these macros is the graph of your query/mutation expressed in a Lispy DSL. Generally speaking, we represent fields as symbols and edges as nested lists with the edge name being the head of that list. For example, ```emacs-lisp (graphql-query (myField1 myField2 (myEdges (edges (node myField3))))) ``` will construct a query that retrieves `myField1`, `myField2`, and `myField3` for every node in `myEdges`. The query is returned as a string without any unnecessary whitespace (i.e., formatting) added. ## Following Edges Multiple edges can of course be followed. Here's an example using GitHub's API: ```emacs-lisp (graphql-query ((viewer login) (rateLimit limit cost remaining resetAt))) ``` ## Passing Arguments Usually, queries need explicit arguments. We pass them in an alist set off by the `:arguments` keyword: ``` emacs-lisp (graphql-query ((repository :arguments ((owner . "github") (name . ($ repo))) (issues :arguments ((first . 20) (states . [OPEN CLOSED])) (edges (node number title url id)))))) ``` As you can see, strings, numbers, vectors, symbols, and variables can all be given as arguments. The above evaluates to the following (formatting added): ``` graphql query { repository (owner: "github", name: $repo) { issues (first: 20, states: [OPEN, CLOSED]) { edges { node { number title url id } } } } } ``` Objects as arguments work, too, though practical examples seem harder to come by: ``` emacs-lisp (graphql-query ((object :arguments ((someVariable . ((someComplex . "object") (with . ($ complexNeeds)))))))) ``` gives ``` graphql query { object ( someVariable: { someComplex: "object", with: $complexNeeds } ) } ``` ## Working with Responses - `graphql-simplify-response-edges` Simplify structures like (field (edges ((node node1values...)) ((node node2values...)))) into `(field (node1values) (node2values))`. ## Keyword Reference - `:arguments` Pass arguments to fields as an alist of parameters (as symbols) to values. See `graphql--encode-argument-value`. - `:op-name`, `:op-params` Operation name/parameters. Given to top-level *query* or *mutation* operations for later re-use. You should rarely (if ever) need to supply these yourself; the `graphql-query` and `graphql-mutation` macros give you natural syntax to do this. ## Planned - `:as` keyword for [aliases][graphql-alias] (`graphql-encode`). - `...` qualifier for [fragments][graphql-fragment] and [inline fragments][graphql-ifragment] (`graphql--encode-object`) [graphql-alias]: http://graphql.org/learn/queries/#aliases [graphql-variable]: http://graphql.org/learn/queries/#variables [graphql-fragment]: http://graphql.org/learn/queries/#fragments [graphql-ifragment]: http://graphql.org/learn/queries/#inline-fragments