Neo4j-GraphQL Extension
Note
|
This is an very early version of GraphQL support for Neo4j. |
This implementation provides a GraphQL API to Neo4j, it comes as library but can also be installed as Neo4j server extension to act as a GraphQL endpoint.
We want to explore three approaches:
-
read schema / metadata from the database provide GraphQL DataFetcher that generate and run Cypher (WIP)
-
make the same work with externally configured schema information (JSON) (TBD)
-
do a direct GraphQL AST to Cypher transformation without bothering with Schema (TBD)
Note
|
Currently only Node and simple Relationship queries are supported. Deeper Relationship queries and aggregations are up next. |
License
Apache License v2
Schema
The library samples the existing data and adds one GraphQLObject for each Node-Label with all the properties and their types found as outputs and input-arguments. Relationship information is collected with direction, type, end-node-labels and degree (to determine single element or collection result).
Installation
git clone https://github.com/neo4j-contrib/neo4j-graphql cd neo4j-graphql mvn clean package cp target/neo4j-graphql-1.0-SNAPSHOT.jar $NEO4J_HOME/plugins echo 'dbms.unmanaged_extension_classes=org.neo4j.graphql=/graphql' >> $NEO4J_HOME/config/neo4j.conf $NEO4J_HOME/bin/neo4j restart
Usage
Run :play movies
in your Neo4j Server, click the statement and run it to insert the basic movie graph.
GraphiQL
Get GraphiQL electron app from: https://github.com/skevy/graphiql-app
If your Neo4j Server runs with auth enabled, add the appropriate Basic-Auth header in the "Edit HTTP Headers" screen.
echo "Authorization: Basic $(echo -n "neo4j:<password>" | base64)"
And then run a query like:
query AllPeopleQuery { Person(name:"Kevin Bacon") { name born ACTED_IN_Movie { title released tagline } } }
You can also use variables or query the schema:
{ __schema { types { name kind description } } }
or
{ __schema { queryType { fields { name, description } } } }
and then query for real data
# query query PersonQuery($name: String!) { Person(name: $name) { name born ACTED_IN_Movie { title released tagline } } } # variables {"name":"Keanu Reeves"}
Procedure
CURL
Query the Schema
curl -u neo4j:<password> -i -XPOST -d'{"query": "query {__schema {types {kind, name, description}}}"}' -H accept:application/json -H content-type:application/json http://localhost:7474/graphql/ {"data":{"__schema":{"types":[{"kind":"OBJECT","name":"QueryType","description":null},{"kind":"OBJECT","name":"Movie","description":"Movie-Node"},....
query {__schema {queryType { kind,description,fields { name } }}}
curl -u neo4j:<password> -i -XPOST -d'{"query": "query AllPeopleQuery { Person {name,born} } }"}' -H accept:application/json -H content-type:application/json http://localhost:7474/graphql/ HTTP/1.1 200 OK Date: Mon, 24 Oct 2016 21:40:15 GMT Content-Type: application/json Access-Control-Allow-Origin: * Transfer-Encoding: chunked Server: Jetty(9.2.9.v20150224) {"data":{"Person":[{"name":"Michael Sheen","born":1969},{"name":"Jack Nicholson","born":1937},{"name":"Nathan Lane","born":1956},{"name":"Philip Seymour Hoffman","born":1967},{"name":"Noah Wyle","born":1971},{"name":"Rosie O'Donnell","born":1962},{"name":"Greg Kinnear","born":1963},{"name":"Susan Sarandon","born":1946},{"name":"Takeshi Kitano","born":1947},{"name":"Gary Sinise","born":1955},{"name":"John Goodman","born":1960},{"name":"Christina Ricci","born":1980},{"name":"Jay Mohr","born":1970},{"name":"Ben Miles","born":1967},{"name":"Carrie Fisher","born":1956},{"name":"Christopher Guest","born":1948},{"name ...
curl -u neo4j:<password> -i -XPOST -d'{"query":"query PersonQuery($name:String!) { Person(name:$name) {name,born} }", "variables":{"name":"Kevin Bacon"}}' -H content-type:application/json http://localhost:7474/graphql/ HTTP/1.1 200 OK Date: Mon, 24 Oct 2016 21:40:38 GMT Content-Type: application/json Access-Control-Allow-Origin: * Transfer-Encoding: chunked Server: Jetty(9.2.9.v20150224) {"data":{"Person":[{"name":"Kevin Bacon","born":1958}]}}
curl -u neo4j:<password> -i -XPOST -d'{"query":"query PersonQuery { Person(name:\"Tom Hanks\") {name, born, ACTED_IN_Movie {title, released} } }"}' -H content-type:application/json http://localhost:7474/graphql/ HTTP/1.1 200 OK Date: Tue, 25 Oct 2016 03:17:08 GMT Content-Type: application/json Access-Control-Allow-Origin: * Transfer-Encoding: chunked Server: Jetty(9.2.9.v20150224) {"data":{"Person":[{"name":"Tom Hanks","born":1956,"ACTED_IN_Movie":[{"title":"Charlie Wilson's War","released":2007},{"title":"A League of Their Own","released":1992},{"title":"The Polar Express","released":2004},{"title":"The Green Mile","released":1999},{"title":"Cast Away","released":2000},{"title":"Apollo 13","released":1995},{"title":"The Da Vinci Code","released":2006},{"title":"Cloud Atlas","released":2012},{"title":"Joe Versus the Volcano","released":1990},{"title":"Sleepless in Seattle","released":1993},{"title":"You've Got Mail","released":1998},{"title":"That Thing You Do","released":1996}]}]}}
Resources
-
GraphQL-Java which we use in this project
-
GraphQL for Postgres as an inspiration of schema → native queries
-
GraphQL inspired Cypher features Map projections and Pattern comprehensions