{"id":13556191,"url":"https://github.com/neo4j-graphql/neo4j-graphql","last_synced_at":"2025-04-05T05:09:50.503Z","repository":{"id":56386322,"uuid":"71757721","full_name":"neo4j-graphql/neo4j-graphql","owner":"neo4j-graphql","description":"GraphQL bindings for Neo4j, generates and runs Cypher","archived":false,"fork":false,"pushed_at":"2022-11-16T00:43:04.000Z","size":3591,"stargazers_count":449,"open_issues_count":93,"forks_count":72,"subscribers_count":43,"default_branch":"3.5","last_synced_at":"2025-03-29T04:12:01.479Z","etag":null,"topics":["automatic-api","graph-database","graphql","graphql-server","neo4j","neo4j-plugin","neo4j-procedures"],"latest_commit_sha":null,"homepage":"https://grandstack.io/docs/neo4j-graphql-plugin.html","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neo4j-graphql.png","metadata":{"files":{"readme":"readme.adoc","changelog":null,"contributing":null,"funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-10-24T06:18:25.000Z","updated_at":"2025-02-26T13:22:48.000Z","dependencies_parsed_at":"2023-01-23T08:00:11.854Z","dependency_job_id":null,"html_url":"https://github.com/neo4j-graphql/neo4j-graphql","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-graphql%2Fneo4j-graphql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-graphql%2Fneo4j-graphql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-graphql%2Fneo4j-graphql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-graphql%2Fneo4j-graphql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neo4j-graphql","download_url":"https://codeload.github.com/neo4j-graphql/neo4j-graphql/tar.gz/refs/heads/3.5","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247289429,"owners_count":20914464,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automatic-api","graph-database","graphql","graphql-server","neo4j","neo4j-plugin","neo4j-procedures"],"created_at":"2024-08-01T12:03:41.427Z","updated_at":"2025-04-05T05:09:50.484Z","avatar_url":"https://github.com/neo4j-graphql.png","language":"Kotlin","funding_links":[],"categories":["Kotlin","graphql","Libraries","数据库开发"],"sub_categories":["Java Libraries","语音合成"],"readme":"= Neo4j-GraphQL Extension\n:img: docs/img\n:branch: 3.5\n\nimage::https://github.com/neo4j-graphql/graphql-community/raw/master/images/neo4j-graphql-logo.png[float=right,width=200]\n\n[NOTE]\nThe plugin is considered end-of-life. It will not be updated for Neo4j 4.0, we recommend to move a middleware based solution using neo4j-graphql-js or neo4j-graphql-java. After a lot of feedback we think separating the GraphQL API from the core database is the better architectural setup.\n\nThis is a GraphQL-Endpoint extension for Neo4j.\nIt is part of the https://grandstack.io[GRANDstack^]\n\n*This readme assumes you are somewhat familiar with http://graphql.org/[GraphQL^] and minimally with http://neo4j.com/developer/cypher[Cypher].*\n\nBased on your _GraphQL schema_, it translates GraphQL _Queries_ and _Mutations_ into Cypher statements and executes them on Neo4j.\n\nIt offers both an *HTTP API*, as well as, Neo4j Cypher *Procedures* to execute and manage your GraphQL API.\n\n\n== Installation\n\nDownload and install http://neo4j.com/download[Neo4j Desktop^]\n\nNeo4j Desktop provides a quick install button for *neo4j-graphql*.\n\nAfter creating your database you can find it under \"Manage\" in the \"Plugins\" tab for a single click install.\n\nimage::{img}/desktop-graphql.jpg[width=600]\n\n=== Use with neo4j-graphql-cli\n\nThis extension is utilized, when you use https://www.npmjs.com/package/neo4j-graphql-cli[`neo4j-graphql-cli`^]\n\nThis tool\n\n1. launches a http://neo4j.com/sandbox[Neo4j Sandbox] with your GraphQL schema\n2. provides the `/graphql/` endpoint,\n3. a Neo4j server,\n4. an hosted GraphiQL for it.\n\n----\nnpm install -g neo4j-graphql-cli\nneo4j-graphql movies-schema.graphql\n----\n\n== Quickstart\n\nTo generate some graph data in Neo4j just run http://localhost:7474/browser?cmd=play\u0026arg=movie%20graph[`:play movie graph`^] in your Neo4j Browser.\n\n=== GraphiQL\n\nThe best tool to use is https://electronjs.org/apps/graphiql[GraphiQL^] the GraphQL UI. Get and install it.\n\nEnter your GraphQL URL, like `+http://localhost:7474/graphql/+` (_note the trailing slash_).\n\nIf your Neo4j Server runs with *authentication enabled*, add the appropriate Basic-Auth (https://www.base64encode.org/[base64 encoded^]) `username:password` header in the \"Edit HTTP Headers\" screen.\n\n.Command to generate the `Authorization` header value.\n----\necho \"Basic $(echo -n \"neo4j:\u003cpassword\u003e\" | base64)\"\n----\n\n=== Uploading a GraphQL Schema\n\nHere is a small example schema for the movie data.\nJust a Movie with actors, and a Person with movies.\n\nSimple properties are mapped directly while the relationships are mapped to fields `movies` and `actors`\n\n.Movies Schema\n[source,graphql]\n----\ntype Movie  {\n  title: String!\n  released: Int\n  actors: [Person] @relation(name:\"ACTED_IN\",direction:IN)\n}\ntype Person {\n  name: String!\n  born: Int\n  movies: [Movie] @relation(name:\"ACTED_IN\")\n}\n----\n\nYou can POST a GraphQL schema to the `/graphql/idl/` endpoint or run the `CALL graphql.idl('schema-text')` procedure.\n\nThe payload is parsed and stored in Neo4j and used subsequently as the backing GraphQL schema for validating and executing queries.\n\n[source,cypher]\n----\nCALL graphql.idl('\ntype Movie  {\n  title: String!\n  released: Int\n  tagline: String\n  actors: [Person] @relation(name:\"ACTED_IN\",direction:IN)\n}\ntype Person {\n  name: String!\n  born: Int\n  movies: [Movie] @relation(name:\"ACTED_IN\")\n}\n')\n----\n\nYou should then be able to see your schema in the _Docs_ section of GraphiQL.\n\nThis also gives you auto-completion, validation and hints when writing queries.\n\nWith `graphql.reset()` you can trigger the reset of you schema.\nBut it also updates automatically if changed on other cluster members.\nLatest after 10 seconds.\n\nTo visualize your GraphQL schema in Neo4j Browser use: `call graphql.schema()`.\n\nimage::{img}/graphql.schema.jpg[width=600]\n\nUsing\n\n----\nRETURN graphql.getIdl()\n----\n\nyou'll get back a string representation of the currently used schema.\n\n=== Auto-Generated Query Types\n\nFrom that schema, the plugin automatically generate *Query Types* for each of the declared types.\n\ne.g. `Movie(title,released,first,offset,_id,orderBy, filter): [User]`\n\n* Each field of the entity is available as _query argument_, with an equality check (plural for list-contains)\n* We also provide a `filter` argument for more complex filtering with nested predicates, also for relation-fields (see https://www.graph.cool/docs/reference/graphql-api/query-api-nia9nushae[graphcool docs])\n* For ordered results there is a `orderBy` argument\n* And `first`, `offset` allow for pagination\n\nNow you can for instance run this query:\n\n.Simple query example\n[source,graphql]\n----\n{ Person(name:\"Kevin Bacon\") {\n    name\n    born\n    movies {\n      title\n      released\n      tagline\n    }\n  }\n}\n----\n\nimage::{img}/graphiql-query1.jpg[]\n\n.Advanced query example\n[source,graphql]\n----\nquery Nineties($released: Int, $letter: String)\n{ Movie(released: $released,\n        filter: {title_starts_with: $letter,\n                 actors_some: { name_contains: $letter}}) {\n    title\n    released\n    actors(first: 3) {\n      name\n      born\n      movies(first: 1, orderBy: title_desc) {\n        title\n        released\n      }\n    }\n  }\n}\n\n# query variables\n{ \"released\":1995, \"letter\":\"A\"}\n----\n\nThis query declares query name and parameters (first line), which are passed separately (\"Query Parameters box\") as JSON.\n\nAnd get this result:\n\nimage::{img}/graphiql-query2.jpg[]\n\n=== Auto-Generated Mutations\n\nAdditionally *Mutations* for each type are created, which return update statistics.\n\ne.g. for the `Movie` type:\n\n* `createMovie(title: ID!, released: Int) : String`\n* `mergeMovie(title: ID!, released: Int) : String`\n* `updateMovie(title: ID!, released: Int) : String`\n* `deleteMovie(title: ID!) : String`\n\nand for it's relationships:\n\n* `addMovieActors(title: ID!, actors:[ID]!) : String`\n* `deleteMovieActors(title: ID!, actors:[ID]!) : String`\n\nThose mutations then allow you to create and update your data with GraphQL.\n\n.Single Mutation\n[source,graphql]\n----\nmutation {\n    createPerson(name:\"Chadwick Boseman\", born: 1977)\n}\n----\n\n.Mutation Result\n[source,json]\n----\n{ \"data\": {\n    \"createPerson\": \"Nodes created: 1\\nProperties set: 2\\nLabels added: 1\\n\"\n  }\n}\n----\n\n.Several Mutations at once\n[source,graphql]\n----\nmutation {\n    pp: createMovie(title:\"Black Panther\", released: 2018)\n    lw: createPerson(name:\"Letitia Wright\", born: 1993)\n    cast: addMovieActors(title: \"Black Panther\",\n          actors:[\"Chadwick Boseman\",\"Letitia Wright\"])\n}\n----\n\nIf multiple mutations are sent as part of the same request, they will be executed in the same transaction (meaning if one of them fails they will all fail). If the same mutation is called multiple times, you _need to use alias prefixes_ to avoid clashes in the returned data, which is keyed on mutation names.\n\nimage::{img}/graphiql-mutation.jpg[]\n\nYou can use those mutations also to https://medium.com/@mesirii/better-data-import-with-graphql-548084a35dfd[load data from CSV or JSON^].\n\n=== Directives\n\nDirectives like `@directiveName(param:value)` can be used to augment the schema with additional meta-information that we use for processing.\n\nYou have already seen the `@relation(name:\"ACTED_IN\", direction:\"IN\")` directive to map entity references to graph relationships.\n\nThe `@cypher` directive is a powerful way of declaring _computed_ fields, query types and mutations with a Cypher statement.\n\n.For instance, `directors`\n[source,graphql]\n----\ntype Movie {\n  ...\n  directors: [Person] @cypher(statement:\"MATCH (this)\u003c-[:DIRECTED]-(d) RETURN d\")\n}\n----\n\n.Register Top-Level Schema Types\n[source,graphql]\n----\nschema {\n   query: QueryType\n   mutation: MutationType\n}\n----\n\n.A custom query\n[source,graphql]\n----\ntype QueryType {\n  ...\n  coActors(name:ID!): [Person] @cypher(statement:\"MATCH (p:Person {name:$name})-[:ACTED_IN]-\u003e()\u003c-[:ACTED_IN]-(co) RETURN distinct co\")\n}\n----\n\n.A custom mutation\n[source,graphql]\n----\ntype MutationType {\n  ...\n  rateMovie(user:ID!, movie:ID!, rating:Int!): Int\n  @cypher(statement:\"MATCH (p:Person {name:$user}),(m:Movie {title:$movie}) MERGE (p)-[r:RATED]-\u003e(m) SET r.rating=$rating RETURN r.rating\")\n}\n----\n\n\n.Full enhanced Schema\n[source,graphql]\n----\ntype Movie  {\n  title: String!\n  released: Int\n  actors: [Person] @relation(name:\"ACTED_IN\",direction:IN)\n  directors: [Person] @cypher(statement:\"MATCH (this)\u003c-[:DIRECTED]-(d) RETURN d\")\n}\ntype Person {\n  name: String!\n  born: Int\n  movies: [Movie] @relation(name:\"ACTED_IN\")\n}\nschema {\n   query: QueryType\n   mutation: MutationType\n}\ntype QueryType {\n  coActors(name:ID!): [Person] @cypher(statement:\"MATCH (p:Person {name:$name})-[:ACTED_IN]-\u003e()\u003c-[:ACTED_IN]-(co) RETURN distinct co\")\n}\ntype MutationType {\n  rateMovie(user:ID!, movie:ID!, rating:Int!): Int\n  @cypher(statement:\"MATCH (p:Person {name:$user}),(m:Movie {title:$movie}) MERGE (p)-[r:RATED]-\u003e(m) SET r.rating=$rating RETURN r.rating\")\n}\n----\n\n=== New Neo4j-GraphQL-Java Integration\n\nCurrently we're working on a https://github.com/neo4j-graphql/neo4j-graphql-java[independent transpiler (neo4j-graphql-java) of GraphQL to Cypher] which can also be used for your own GraphQL servers or middleware on the JVM.\n\nThis takes a given GraphQL schema, augments it and then uses that schema to generate Cypher queries from incoming GraphQL queries.\n\nThere are small examples of writing GraphQL servers in the repository, but we also wanted to make the new implementation available for testing.\n\nThat's why we link:src/main/kotlin/GraphQLResourceExperimental.kt[integrated] the new transpiler at the URL: http://localhost:7474/graphql/experimental/ in this plugin, so that you can test it out.\nIt uses the schema of the main implementation.\n\nCurrently supported features are:\n\n* parse SDL schema\n* resolve query fields via result types\n* handle arguments as equality comparisons for top level and nested fields\n* handle relationships via @relation directive on schema fields\n* @relation directive on types for rich relationships (from, to fields for start \u0026 end node)\n* filter for top-level query-fields\n* handle first, offset arguments\n* argument types: string, int, float, array\n* request parameter support\n* parametrization for cypher query\n* aliases\n* inline and named fragments\n* auto-generate query fields for all objects\n* @cypher directive for fields to compute field values, support arguments\n* auto-generate mutation fields for all objects to create, update, delete\n* @cypher directive for top level queries and mutations, supports arguments\n\nFor more details see the https://github.com/neo4j-graphql/neo4j-graphql-java/[readme of the transpiler repository].\n\nHere is a query example against the movie graph:\n\n[source,graphql]\n----\n{\n  person(born:1950) {\n    name, born\n    movies(first: 4) {\n      title\n      actors {\n        name\n      }\n    }\n  }\n}\n----\n\nimage:docs/img/neo4j-graphql-java-experimental.jpg[width:800]\n\n=== Procedures\n\nThis library also comes with Cypher Procedures to execute GraphQL from within Neo4j.\n\n.Simple Procedure Query\n[source,cypher]\n----\nCALL graphql.query('{ Person(born: 1961) { name, born } }')\n----\n\n.Advanced Procedure Query with parameters and post-processing\n[source,cypher]\n----\nWITH 'query ($year:Long,$limit:Int) { Movie(released: $year, first:$limit) { title, actors {name} } }' as query\n\nCALL graphql.query(query,{year:1995,limit:5}) YIELD result\n\nUNWIND result.Movie as movie\nRETURN movie.title, [a IN movie.actors | a.name] as actors\n----\n\nimage::{img}/graphql.execute.jpg[]\n\n.Update with Mutation\n[source,cypher]\n----\nCALL graphql.execute('mutation { createMovie(title:\"The Shape of Water\", released:2018)}')\n----\n\n== Other Information\n\n*Please* leave link:/issues[Feedback and Issues^]\n\nYou can get quick answers on http://neo4j.com/slack[Neo4j-Users Slack^] in the https://neo4j-users.slack.com/messages/C5ET7S24R[`#neo4j-graphql` channel^]\n\nLicense: Apache License v2.\n\nThis branch for Neo4j {branch}.x\n\nimage:https://travis-ci.org/neo4j-contrib/neo4j-graphql.svg?branch={branch}[\"Build Status\", link=\"https://travis-ci.org/neo4j-contrib/neo4j-graphql\"]\n\n== Features\n\n// tag::features[]\n\n[options=header,cols=\"a,2a,3m\"]\n|===\n\n| name | information | example\n| entities\n| each node label represented as entity\n| { Person {name,born} }\n\n| multi entities\n| multiple entities per query turned into `UNION`\n| { Person {name,born} Movie {title,released} }\n\n| property fields\n| via sampling property names and types are determined\n| { Movie {title, released} }\n\n| field parameters\n| all properties can be used as filtering (exact/list) input parameters, will be turned into Cypher parameters\n| { Movie(title:\"The Matrix\") {released,tagline} }\n\n| query parameters\n| passed through as Cypher parameters\n| query MovieByParameter ($title: String!) { Person(name:$name) {name,born} }\n\n| filter arguments\n| nested input types for arbitrary filtering on query types and fields\n| { Company(filter: { AND: { name_contains: \"Ne\", country_in [\"SE\"]}}) { name } }\n\n| filter arguments for relations\n| filtering on relation fields, suffixes (\"\",not,some, none, single, every)\n| { Company(filter: { employees_none { name_contains: \"Jan\"}, employees_some: { gender_in : [female]}, company_not: null }) { name } }\n\n| relationships\n| via a `@relationship` annotated field, optional direction\n| type Person { name: String, movies : Movie @relation(name:\"ACTED_IN\", direction:OUT) }\n\n| ordering\n| via an extra `orderBy` parameter\n| query PersonSortQuery { Person(orderBy:[name_desc,born_desc]) {name,born}}\n\n| pagination\n| via `first` and `offset` parameters\n| query PagedPeople { Person(first:10, offset:20) {name,born}}\n\n| schema first IDL support\n| define schema via IDL\n| :POST /graphql/idl \"type Person {name: String!, born: Int}\"\n\n| Mutations | create/delete mutations inferred from the schema |\ncreateMovie(title:ID!, released:Int)\nupdateMovie(title:ID!, released:Int)\ndeleteMovie(title:ID!)\n\ncreateMoviePersons(title:ID!,persons:[ID!]) +\ndeleteMoviePersons(title:ID!,persons:[ID!])\n\n| Cypher queries\n| `@cypher` directive on fields and types, parameter support\n| actors : Int @cypher(statement:\"RETURN size( (this)\u003c -[:ACTED_IN]-() )\")\n\n| Cypher updates\n| Custom mutations by executing `@cypher` directives\n| createPerson(name: String) : Person @cypher(statement:\"CREATE (p:Person {name:{name}}) RETURN p\")\n\n| extensions\n| extra information returned\n| fields are: columns, query, warnings, plan, type READ_ONLY/READ_WRITE,\n// | directive | directives control cypher prefixes, *note that directives have to be set at the first entity* |\n// | directive - query plan | `@profile / @explain` will be returned in extra field `extensions` | query UserQuery { User @profile {name} }\n\n// | directive - version | set cypher version to use `@version(3.0,3.1,3.2)` | query UserQuery { User @version(3.0) {name} }\n|===\n\n\n[NOTE]\n`@cypher` directives can have a  `passThrough:true` argument, that gives sole responsibility for the nested query result for this field to your Cypher query.\nYou will have to provide all data/structure required by client queries.\nOtherwise, we assume if you return object-types that you will return the appropriate nodes from your statement.\n\n// end::features[]\n\n== Advanced Usage\n\nThe extension works with Neo4j 3.x, the code on this branch is for *{branch}*.\n\nPlease consult the https://neo4j.com/docs/operations-manual/current/configuration/file-locations/[Neo4j documentation^] for file locations for the other editions on the different operating systems.\n\n=== Manual Installation\n\n1. Download the https://github.com/neo4j-graphql/neo4j-graphql/releases[appropriate neo4j-graphql release^] for your version.\n2. Copy the _jar-file_ into Neo4j's `plugins` directory\n3. Edit the Neo4j settings (`$NEO4J_HOME/conf/neo4j.conf`) to add: +\n`dbms.unmanaged_extension_classes=org.neo4j.graphql=/graphql`\n4. You might need to add `,graphql.*` if your config contains this line: +\n`dbms.security.procedures.whitelist=`\n5. (Re)start your Neo4j server\n\nNOTE: _Neo4j Desktop_: the configuration is available under *Manage -\u003e Settings*, the `plugins` folder via *Open Folder*.\n\n[NOTE]\n====\nIf you run Neo4j via Docker:\n\n* put the jar-file into a `/plugins` directory and make it available to the container via `-v /path/to/plugins:/plugins`\n* also add to your environment: `+-e NEO4J_dbms_unmanaged__extension__classes=org.neo4j.graphql=/graphql+`.\n====\n\n=== Building manually\n\n[subst=attributes]\n----\ngit clone https://github.com/neo4j-graphql/neo4j-graphql\ncd neo4j-graphql\ngit checkout {branch}\nmvn clean package\ncp target/neo4j-graphql-*.jar $NEO4J_HOME/plugins\necho 'dbms.unmanaged_extension_classes=org.neo4j.graphql=/graphql' \u003e\u003e $NEO4J_HOME/conf/neo4j.conf\n$NEO4J_HOME/bin/neo4j restart\n----\n\nNOTE: You might need to add `,graphql.*` if your config contains this line: `dbms.security.procedures.whitelist=`\n\n=== Schema from Graph\n\nIf you didn't provide a GraphQL schema, we try to derive one from the existing graph data.\nFrom sampling the data we add a `type` for each Node-Label with all the properties and their types found as fields.\n\n// Relationship information is collected with direction, type, end-node-labels and degree (to determine single element or collection result).\n// Additional labels on a node are added as GraphQLInterface's.\nEach relationship-type adds a reference field to the node type, named `aType` for `A_TYPE`.\n// Each relationship-type and end-node label is added as a virtual property to the node type, named `TYPE_Label` for outgoing and `Label_TYPE` for incoming relationships.\n\n\n////\n\nYou can also use variables or query the schema:\n\n.Which types are in the schema\n----\n{\n  __schema {\n    types {\n      name\n      kind\n      description\n    }\n  }\n}\n----\n\nor\n\n.Which types are available for querying\n----\n{\n  __schema {\n    queryType {\n      fields { name, description }\n    }\n  }\n}\n----\n\nand then query for real data\n\n----\n# query\nquery PersonQuery($name: String!) {\n  Person(name: $name) {\n    name\n    born\n    actedIn {\n      title\n      released\n      tagline\n    }\n  }\n}\n# variables\n{\"name\":\"Keanu Reeves\"}\n----\n////\n\n\n=== Procedures\n\nYou can even visualize remote graphql schemas, e.g. here from the https://developer.github.com/v4/[GitHub GraphQL API^].\nMake sure to generate the https://developer.github.com/v4/guides/forming-calls/#authenticating-with-graphql[Personal Access Token^] to use in your account settings.\n\n[source,cypher]\n----\ncall graphql.introspect(\"https://api.github.com/graphql\",{Authorization:\"bearer d8xxxxxxxxxxxxxxxxxxxxxxx\"})\n----\n\nimage:{img}/graphql.introspect-github.jpg[width=600]\n\n////\n\n== Examples\n\nSome more examples\n\n.Relationship Argument\n----\nquery MoviePersonQuery {\n  Movie {\n    title\n    actedIn(name:\"Tom Hanks\") {\n      name\n    }\n  }\n}\n----\n\n.Nested Relationships\n----\nquery PersonMoviePersonQuery {\n  Person {\n    name\n    actedIn {\n      title\n      actedIn {\n        name\n      }\n    }\n  }\n}\n----\n\n.Sorting\n----\nquery PersonQuery {\n  Person(orderBy: [age_asc, name_desc]) {\n    name\n    born\n  }\n}\n----\n////\n\n== Resources\n\n=== Neo4j-GraphQL\n\n* http://grandstack.io[GRAND Stack (GraphQL React Apollo Neo4j Database)^]\n* https://github.com/neo4j-graphql[neo4j-graphql^] Tools and Libraries related to Neo4j's GraphQL support\n* https://neo4j.com/developer/graphql[GraphQL page^] on neo4j.com\n* https://neo4j.com/blog/cypher-graphql-neo4j-3-1-preview/[GraphQL inspired Cypher features^] Map projections and Pattern comprehensions\n\n=== Libraries \u0026 Tools\n\n* https://facebook.github.io/graphq[GraphQL Specification^]\n* https://github.com/graphql-java/graphql-java[GraphQL-Java^] which we use in this project\n* https://github.com/skevy/graphiql-app[GraphiQL Electron App^]\n\n////\n\n=== Similar Projects\n\n* https://github.com/solidsnack/GraphpostgresQL[GraphQL for Postgres^] as an inspiration of schema -\u003e native queries\n* https://github.com/jhwoodward/neo4j-graphQL[Schema Based GraphQL to Cypher in JavaScript]\n* https://github.com/jameskyburz/graphqlcypherquery[GraphQL to Cypher translator (w/o schema)]\n* https://github.com/JamesKyburz/graphql2cypher[GraphQL parser to Cypher]\n\n////\n\n// * https://github.com/facebook/dataloader\n// * http://graphql.org/learn/serving-over-http/[Serving over HTTP]\n\n////\necho \"Authorization: Basic $(echo -n \"neo4j:test\" | base64)\"\n\"Authorization: Basic bmVvNGo6dGVzdA==\"\n////\n\n////\n\n== Using an http client (curl)\n\n=== POST Schema IDL\n\n----\ncurl  -u neo4j:\u003cpassword\u003e -i -XPOST -d'type Person { name: String, born: Int }' http://localhost:7474/graphql/idl/\n\n{Person=MetaData{type='Person', ids=[], indexed=[], properties={name=PropertyType(name=String, array=false, nonNull=false), born=PropertyType(name=Int, array=false, nonNull=false)}, labels=[], relationships={}}}\n\n\ncurl  -u neo4j:\u003cpassword\u003e -i -XPOST -d @movies-schema.graphql http://localhost:7474/graphql/idl/\n----\n\n\n=== Query the Schema\n\n----\ncurl  -u neo4j:\u003cpassword\u003e -i -XPOST -d'{\"query\": \"query {__schema {types {kind, name, description}}}\"}' -H accept:application/json -H content-type:application/json http://localhost:7474/graphql/\n\n{\"data\":{\"__schema\":{\"types\":[{\"kind\":\"OBJECT\",\"name\":\"QueryType\",\"description\":null},{\"kind\":\"OBJECT\",\"name\":\"Movie\",\"description\":\"Movie-Node\"},....\n----\n\n----\nquery {__schema {queryType {\n  kind,description,fields {\n    name\n  }\n}}}\n----\n\n=== Get All People\n\n----\ncurl  -u neo4j:\u003cpassword\u003e  -i -XPOST -d'{\"query\": \"query AllPeopleQuery { Person {name,born} } }\"}' -H accept:application/json -H content-type:application/json http://localhost:7474/graphql/\n\n\nHTTP/1.1 200 OK\nDate: Mon, 24 Oct 2016 21:40:15 GMT\nContent-Type: application/json\nAccess-Control-Allow-Origin: *\nTransfer-Encoding: chunked\nServer: Jetty(9.2.9.v20150224)\n\n{\"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\n...\n----\n\n=== Get one Person by name with Parameter\n\n----\ncurl  -u neo4j:\u003cpassword\u003e -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/\n\nHTTP/1.1 200 OK\nDate: Mon, 24 Oct 2016 21:40:38 GMT\nContent-Type: application/json\nAccess-Control-Allow-Origin: *\nTransfer-Encoding: chunked\nServer: Jetty(9.2.9.v20150224)\n\n{\"data\":{\"Person\":[{\"name\":\"Kevin Bacon\",\"born\":1958}]}}\n----\n\n=== Get one Person by name literal with related movies\n\n----\ncurl  -u neo4j:\u003cpassword\u003e -i -XPOST -d'{\"query\":\"query PersonQuery { Person(name:\\\"Tom Hanks\\\") {name, born, actedIn {title, released} } }\"}' -H content-type:application/json http://localhost:7474/graphql/\nHTTP/1.1 200 OK\nDate: Tue, 25 Oct 2016 03:17:08 GMT\nContent-Type: application/json\nAccess-Control-Allow-Origin: *\nTransfer-Encoding: chunked\nServer: Jetty(9.2.9.v20150224)\n\n{\"data\":{\"Person\":[{\"name\":\"Tom Hanks\",\"born\":1956,\"actedIn\":[{\"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}]}]}}\n----\n\n=== Schema first\n\n----\ncurl -X POST http://localhost:7474/graphql/idl -d 'type Person {\n            name: String!\n            born: Int\n            movies: [Movie] @relation(name:\"ACTED_IN\")\n            totalMoviesCount: Int @cypher(statement: \"WITH {this} AS this MATCH (this)-[:ACTED_IN]-\u003e() RETURN count(*) AS totalMoviesCount\")\n            recommendedColleagues: [Person] @cypher(statement: \"WITH {this} AS this MATCH (this)-[:ACTED_IN]-\u003e()\u003c-[:ACTED_IN]-(other) RETURN other\")\n        }\n\n        type Movie  {\n            title: String!\n            released: Int\n            tagline: String\n            actors: [Person] @relation(name:\"ACTED_IN\",direction:IN)\n         }' -u neo4j:****\n----\n\n////\n\n////\n== TODO\n\n* Non-Null and Nullable Input and Output Types\n* https://www.reindex.io/docs/graphql-api/connections/#connection-arguments[Pagination]: Skip and Limit (first,last,after,before,skip,limit)\n* √ https://www.reindex.io/docs/graphql-api/connections/#orderby[orderBy] with enum _PersonOrdering { name_asc,name_desc,... }\n* https://www.reindex.io/docs/graphql-api/connections/#filtering[Filtering] with support of a object argument for an input-argument-field, with key=comparator, and value compare-value +\n  `(status: {eq/neq:true}, createdAt: { gte: \"2016-01-01\", lt: \"2016-02-01\"}, tags: {isNull:false, includes/excludes: \"foo\"})`\n* Handle result aggregation.\n* How to handle Geospatial and other complex input types\n* √ Support for Directives, e.g. to specify the cypher compiler or runtime? or special handling for certain fields or types\n* √ Add `extensions` result value for query statistics or query plan, depending on directives given, e.g. contain the generated cypher query as well\n* @skip, @include directives, check if they are handled by the library\n* √ handle nested relationships as optional or non-optional (perhaps via nullable?) or directive\n* √ project non-found nested results as null vs. map with null-value entries\n* https://facebook.github.io/relay/docs/graphql-connections.html#content[Connection] add support for edges / nodes special properties\n* √ Support 3.1+ via pattern comprehensions and map projections\n* Improvements: consider replacing MetaData with GraphQL types,\n* check if there is a direct conversion from parsed data (AST-Nodes) to graphql-schema types\n\n////\n\n////\n== Rewrite\n\n* Replace Metadata with GraphQLTypes / Interfaces -\u003e use GraphQLReferenceType to break cyclic dependencies\n* Keep tests\n* Store meta-information in directives (@relation, @isUnique etc.)\n* Change db-scanner to generate GraphQL-Types\n* Use schema parser to turn IDL into types\n* Add transformations, that e.g. adds dynamic query and mutation types with @cypher directives and custom enums/input objects\n* Add transformation for pagination, filter, ordering on all primitive fields\n* Allow for further transformations\n* Unify custom and generated dynamic fields (handle mutations and root queries separately with graphql.run procedure, inline with function\n* Generate Cypher query from current query + schema information\n* Build easy transform functions from schema objects into simpler data clases e.g. a Cypher class with (query, parameters) or Relationship(field,type,direction,start-label,end-label)\n* The only \"wiring\" we have to add is for top level objects\n\n1. Schema source\n2. Schema\n3. Transform/Augment with custom queries \u0026 mutations\n4. Generate queries based on schema + query\n\n== Open\n\n* Unions\n* Subscriptions\n\n== Permissions\n\n* provide username, adminstatus and roles as parameters to cypher query\n* make them queryable from graphql with __User {name, roles, admin, active}\n* support the permission queries from graph cool using the user and their roles\n////\n\n\n== Neo4j Admin API\n\nThe project also contains an experimental endpoint to expose procedures deployed into Neo4j (built-in and external) as a GraphQL admin API endpoint.\n\nIf you access `/graphql/admin` in GraphiQL or GraphQL Playground, you should see those separated into queries and mutations in the schema.\n\nYou have to explicitely allow procedures to be exposed, via the config setting `graphql.admin.procedures.(read/write)` with either Neo4j procedure syntax or admin-endpoint field names.\nBy setting it to:\n\n----\ngraphql.admin.procedures.read=db.*,dbms.components,dbms.queryJ*\ngraphql.admin.procedures.write=db.create*,dbIndexExplicitFor*\n----\n\nFor documentation on each please check the provided description or the documentation of the original procedure in the Neo4j or other manuals.\n\nimage::{img}/neo4j-graphql-admin-simple.png[]\n\nYou will have to provide the appropriate user credentials as HTTP Basic-Auth headers, the procedures are executed under the priviledges of that user.\n\nYou can read more about it https://medium.com/@mesirii/using-a-graphql-api-for-database-administration[in this article^].\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneo4j-graphql%2Fneo4j-graphql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneo4j-graphql%2Fneo4j-graphql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneo4j-graphql%2Fneo4j-graphql/lists"}