Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/r0man/grafeo
A GraphQL document and schema language based on S-expressions in Clojure & ClojureScript
https://github.com/r0man/grafeo
alumbra clojure clojurescript dsl graphql lisp
Last synced: 3 months ago
JSON representation
A GraphQL document and schema language based on S-expressions in Clojure & ClojureScript
- Host: GitHub
- URL: https://github.com/r0man/grafeo
- Owner: r0man
- License: epl-1.0
- Created: 2019-01-12T12:20:17.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2020-04-25T09:42:29.000Z (over 4 years ago)
- Last Synced: 2024-10-07T23:48:18.668Z (3 months ago)
- Topics: alumbra, clojure, clojurescript, dsl, graphql, lisp
- Language: Clojure
- Homepage:
- Size: 65.4 KB
- Stars: 11
- Watchers: 4
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.org
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
* Grafeo
#+author: r0man
#+LANGUAGE: en[[https://clojars.org/grafeo][https://img.shields.io/clojars/v/grafeo.svg]]
[[https://travis-ci.org/r0man/grafeo][https://travis-ci.org/r0man/grafeo.svg]]
[[https://versions.deps.co/r0man/grafeo][https://versions.deps.co/r0man/grafeo/status.svg]]
[[https://versions.deps.co/r0man/grafeo][https://versions.deps.co/r0man/grafeo/downloads.svg]]/Grafeo/ is [[https://clojure.org][Clojure]] and [[https://github.com/clojure/clojurescript][ClojureScript]] library that provides a
S-expression based language for [[https://graphql.org/][GraphQL]] documents and schemas.** Usage
Require the library.
#+BEGIN_SRC clojure :exports code :results silent
(require '[clojure.pprint :refer [pprint]])
(require '[grafeo.core :as gql])
#+END_SRCDefine a GraphQL document in s-expression format. Take a look at
the [[https://github.com/r0man/grafeo/tree/master/doc][doc]] folder to learn how to write GraphQL documents and schemas
in S-expression format.#+BEGIN_SRC clojure :exports code :results silent
(def my-document
'((human
[(id "1000")]
name
(height [(unit FOOT)]))))
#+END_SRC*** Pretty printing
Pretty print the GraphQL document.
#+BEGIN_SRC clojure :exports both :results output
(gql/pprint my-document)
#+END_SRC#+RESULTS:
: query {
: human(id: "1000") {
: name
: height(unit: FOOT)
: }
: }*** Alumbra
[[https://github.com/alumbra][Alumbra]] is a very complete GraphQL library for Clojure. It
provides an [[https://github.com/alumbra/alumbra.analyzer][analyzer]], a [[https://github.com/alumbra/alumbra.parser][parser]] and Clojure [[https://clojure.org/guides/spec][Specs]] around
GraphQL. When parsing a /Grafeo/ GraphQL document in S-expressions
format it is converted into Alumbra's AST format.The following example parses the GraphQL document and prints the
[[https://github.com/alumbra][Alumbra]] AST.#+BEGIN_SRC clojure :exports both :results output
(binding [*print-namespace-maps* false]
(pprint (gql/parse-document my-document)))
#+END_SRC#+RESULTS:
#+begin_example
{:alumbra/metadata {:column 0, :row 0},
:alumbra/operations
[{:alumbra/metadata {:column 0, :row 0},
:alumbra/operation-type "query",
:alumbra/selection-set
[{:alumbra/field-name "human",
:alumbra/metadata {:column 0, :row 0},
:alumbra/arguments
[{:alumbra/argument-name "id",
:alumbra/argument-value
{:alumbra/metadata {:column 0, :row 0},
:alumbra/string "1000",
:alumbra/value-type :string},
:alumbra/metadata {:column 0, :row 0}}],
:alumbra/selection-set
[{:alumbra/field-name "name",
:alumbra/metadata {:column 0, :row 0}}
{:alumbra/field-name "height",
:alumbra/metadata {:column 0, :row 0},
:alumbra/arguments
[{:alumbra/argument-name "unit",
:alumbra/argument-value
{:alumbra/enum "FOOT",
:alumbra/metadata {:column 0, :row 0},
:alumbra/value-type :enum},
:alumbra/metadata {:column 0, :row 0}}]}]}]}]}
#+end_example*** JavaScript
In the JavaScript world, GraphQL clients like [[https://www.apollographql.com/docs/react/][Apollo]] and [[https://facebook.github.io/relay/][Relay]] use
a different AST format. /Grafeo/ can translate between the Alumbra
and JavaScript formats.The following example parses the GraphQL document and prints the
JavaScript AST.#+BEGIN_SRC clojure :exports both :results output
(pprint (gql/parse-document-js my-document))
#+END_SRC#+RESULTS:
#+begin_example
{:definitions
[{:directives [],
:kind "OperationDefinition",
:loc {:startToken {:column 0, :line 0, :start nil}},
:name nil,
:operation "query",
:selectionSet
{:kind "SelectionSet",
:selections
[{:alias nil,
:arguments
[{:kind "Argument",
:loc {:startToken {:column 0, :line 0, :start nil}},
:name
{:kind "Name",
:loc {:startToken {:column 0, :line 0, :start nil}},
:value "id"},
:value
{:block false,
:kind "StringValue",
:loc {:startToken {:column 0, :line 0, :start nil}},
:value "1000"}}],
:directives [],
:kind "Field",
:loc {:startToken {:column 0, :line 0, :start nil}},
:name
{:kind "Name",
:loc {:startToken {:column 0, :line 0, :start nil}},
:value "human"},
:selectionSet
{:kind "SelectionSet",
:selections
[{:alias nil,
:arguments [],
:directives [],
:kind "Field",
:loc {:startToken {:column 0, :line 0, :start nil}},
:name
{:kind "Name",
:loc {:startToken {:column 0, :line 0, :start nil}},
:value "name"},
:selectionSet nil}
{:alias nil,
:arguments
[{:kind "Argument",
:loc {:startToken {:column 0, :line 0, :start nil}},
:name
{:kind "Name",
:loc {:startToken {:column 0, :line 0, :start nil}},
:value "unit"},
:value
{:kind "EnumValue",
:loc {:startToken {:column 0, :line 0, :start nil}},
:value "FOOT"}}],
:directives [],
:kind "Field",
:loc {:startToken {:column 0, :line 0, :start nil}},
:name
{:kind "Name",
:loc {:startToken {:column 0, :line 0, :start nil}},
:value "height"},
:selectionSet nil}]}}]},
:variableDefinitions []}],
:kind "Document",
:loc {:startToken {:column 0, :line 0, :start nil}}}
#+end_example*** HTTP Client
/Grafeo/ provides a [[https://github.com/dakrone/clj-http][clj-http]] based HTTP client for GraphQL. The
following example show how to query a GraphQL based server. Start
the SWAPI server in this repository on
[[http://localhost:4000/graphql][http://localhost:4000/graphql]].#+BEGIN_SRC clojure :exports both :results silent
node server.js
#+END_SRCRequire the HTTP client.
#+BEGIN_SRC clojure :exports both :results silent
(require '[grafeo.http :as http])
#+END_SRCDefine the server we are talking to.
#+BEGIN_SRC clojure :exports both :results silent
(def my-server
{:scheme :http
:server-name "localhost"
:server-port 4000})
#+END_SRCQuery the local Star Wars API server and print the result.
#+BEGIN_SRC clojure :exports both :results output
(->> (http/request my-server my-document) :body pprint)
#+END_SRC#+RESULTS:
: {:data {:human {:name "Luke Skywalker", :height 5.6430448}}}With variables.
#+BEGIN_SRC clojure :exports both :results output
(->> (http/request
my-server
'((query
HeroNameAndFriends
[($episode Episode)]
(hero
[(episode $episode)]
name
(friends name))))
{:variables {:episode "JEDI"}})
:body pprint)
#+END_SRC#+RESULTS:
: {:data
: {:hero
: {:name "R2-D2",
: :friends
: [{:name "Luke Skywalker"}
: {:name "Han Solo"}
: {:name "Leia Organa"}]}}}** License
Copyright © 2019 [[https://github.com/r0man][r0man]]
Distributed under the Eclipse Public License, the same as Clojure.