{"id":14975979,"url":"https://github.com/neo4j-graphql/neo4j-graphql-java","last_synced_at":"2025-07-29T15:11:20.895Z","repository":{"id":39864315,"uuid":"147095795","full_name":"neo4j-graphql/neo4j-graphql-java","owner":"neo4j-graphql","description":"Neo4j Labs Project: Pure JVM translation for GraphQL queries and mutations to Neo4j's Cypher","archived":false,"fork":false,"pushed_at":"2025-01-16T21:00:33.000Z","size":4448,"stargazers_count":105,"open_issues_count":61,"forks_count":49,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-05-24T04:05:59.419Z","etag":null,"topics":["cypher","graphql","graphql-client","graphql-middleware","java","kotlin","neo4j","transpiler"],"latest_commit_sha":null,"homepage":"","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","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-09-02T15:04:40.000Z","updated_at":"2025-02-19T07:27:31.000Z","dependencies_parsed_at":"2024-04-11T20:25:15.227Z","dependency_job_id":"635ebd6f-fa0e-40f7-b643-349e9e4fc9e0","html_url":"https://github.com/neo4j-graphql/neo4j-graphql-java","commit_stats":{"total_commits":206,"total_committers":19,"mean_commits":"10.842105263157896","dds":0.5339805825242718,"last_synced_commit":"f2f96aa15c9454186c71598a04f95a6278cd14d4"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/neo4j-graphql/neo4j-graphql-java","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-graphql%2Fneo4j-graphql-java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-graphql%2Fneo4j-graphql-java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-graphql%2Fneo4j-graphql-java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-graphql%2Fneo4j-graphql-java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neo4j-graphql","download_url":"https://codeload.github.com/neo4j-graphql/neo4j-graphql-java/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neo4j-graphql%2Fneo4j-graphql-java/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267706449,"owners_count":24131135,"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","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["cypher","graphql","graphql-client","graphql-middleware","java","kotlin","neo4j","transpiler"],"created_at":"2024-09-24T13:53:04.841Z","updated_at":"2025-07-29T15:11:20.843Z","avatar_url":"https://github.com/neo4j-graphql.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"= JVM Library to translate GraphQL queries and mutations to Neo4j's Cypher\n:version: 1.9.0\n:toc:\n:toclevels: 1\n:toc-title: Quick Links\n\nNOTE: This is a https://neo4j.com/labs/[Neo4j Labs Project^], it is not supported by Neo4j engineering or support and developed on an best-effort basis.\nIt is also not functionally equivalent to the https://github.com/neo4j/graphql[neo4j-graphql (Javascript) library and API^] even as we try to stay close to it.\nPlease use the official library for a JavaScript based GraphQL Middleware for production use-cases.\n\nThis is a https://graphql.org[GraphQL] to https://neo4j.com/developer/cypher[Cypher] transpiler written in Kotlin.\n\nLicense: Apache 2.\n\n== How does it work\n\nThis library\n\n1. parses a GraphQL schema and\n2. uses the information of the annotated schema to translate _GraphQL_ queries and parameters into _Cypher_ queries and parameters.\n\nThose Cypher queries can then be executed, e.g. via the Neo4j-Java-Driver (or other JVM drivers) against the graph database and the results can be returned directly to the caller.\n\nThe request, result and error handling is not part of this library, but we provide demo programs on how to use it in different languages.\n\nNOTE: All the \u003c\u003cfeatures,supported features\u003e\u003e are listed and explained below, more detailed docs will be added in time.\n\n== Examples\n\nFor complex examples take a look at our link:examples/readme.adoc[example projects]\n\n== API compatibility to @neo4j/graphql\n\nSince the javascript pendant of this library (neo4j-graphql-js) has majored into a neo4j product, we want to migrate our augmented schema, to match as much as possible to the one of the https://github.com/neo4j/graphql[`@neo4j/graphql`].\nTherefore, we created a https://github.com/neo4j-graphql/neo4j-graphql-java/issues?q=label%3AAPI-Alignment[list of issues to track progress].\n\nWe will try to make the migration as smooth as possible.\nFor this purpose we will support the old, and the new way of schema augmentation until the next major release.\nTo already test the new features, you can enable them via link:core/src/main/kotlin/org/neo4j/graphql/SchemaConfig.kt[some setting in the `SchemaConfig`]\n\n== FAQ\n\n=== How does this relate to the other neo4j graphql libraries?\n\nhttps://grandstack.io[The GRANDstack^] is a full-stack package that integrates React frontends via GraphQL through `neo4j-graphql-js` with Neo4j.\n\nSimilar to https://grandstack.io/docs/neo4j-graphql-js-quickstart[`neo4j-graphql-js`] this library focuses on query translation, just for the *JVM* instead of Node.js.\nIt does not provide a server (except as examples) or other facilities but is meant to be used as a dependency included for a single purpose.\n\nWe plan to replace the code in the current Neo4j server plugin `neo4j-graphql` with a single call to this library.\nThe server plugin could still exist as an example that shows how to handle request-response and error-handling, and perhaps some minimal schema management but be slimmed down to a tiny piece of code.\n\n=== How does this related to graphql-java\n\nThis library uses `graphql-java` under the hood for parsing of schema and queries, and managing the GraphQL state and context.\nBut *not for nested field resolvers or data fetching*.\n\nIf you wanted, you could combine `graphql-java` resolvers with this library to have a part of your schema handled by Neo4j.\n\nThanks a lot to the maintainers of `graphql-java` for the awesome library.\n\nNOTE: We also use `neo4j-opencypher-dsl` provided graciously by the spring-data-neo4j-rx project to generate our cypher queries.\n\n== Usage\n\nYou can use the library as dependency: `org.neo4j:neo4j-graphql-java:{version}` in any JVM program.\n\nThe basic usage should be:\n\n[source,kotlin]\n----\nval schema =\n        \"\"\"\n        type Person {\n            name: ID!\n            age: Int\n        }\n        # Optional if you use generated queries\n        type Query {\n            person : [Person]\n            personByName(name:ID) : Person\n        }\"\"\"\n\nval query = \"\"\" { p:personByName(name:\"Joe\") { age } } \"\"\"\n\nval schema = SchemaBuilder.buildSchema(idl)\nval ctx = QueryContext()\nval (cypher, params) = Translator(schema).translate(query, params, ctx)\n\n// generated Cypher\ncypher == \"MATCH (p:Person) WHERE p.name = $pName RETURN p {.age} as p\"\n----\n\nYou find more usage examples in the:\n\n* link:core/src/test/resources/movie-tests.adoc[Movie TCK]\n* link:core/src/test/resources/filter-tests.adoc[Filter TCK]\n* link:core/src/test/resources/cypher-directive-tests.adoc[Cypher Directive TCK]\n* link:core/src/test/resources/property-tests.adoc[Property TCK]\n* link:core/src/test/resources/translator-tests1.adoc[Translator 1 TCK]\n* link:core/src/test/resources/translator-tests2.adoc[Translator 2 TCK]\n* link:core/src/test/resources/translator-tests3.adoc[Translator 3 TCK]\n* link:core/src/test/resources/translator-tests-custom-scalars.adoc[Translator custom scalars TCK]\n* link:core/src/test/resources/optimized-query-for-filter.adoc[Alternative Filter TCK]\n\n== Demo\n\nHere is a minimalistic example in Groovy using the Neo4j-Java driver and Spark-Java as webserver.\nIt is running against a Neo4j instance at `bolt://localhost` (username: `neo4j`, password: `s3cr3t`) containing the `:play movies` graph.\n\n(You can also use a link:core/src/test/kotlin/demo/GraphQLServer.kt[Kotlin based server example].)\n\nIn case you wand to bind the neo4j driver directly to the graphql schema you can\nlink:core/src/test/kotlin/DataFetcherInterceptorDemo.kt[use the DataFetchingInterceptor to\nintercept the cypher queries].\n\n[source,groovy,subs=attributes]\n----\n// Simplistic GraphQL Server using SparkJava\n@Grapes([\n  @Grab('com.sparkjava:spark-core:2.7.2'),\n  @Grab('org.neo4j.driver:neo4j-java-driver:1.7.2'),\n  @Grab('com.google.code.gson:gson:2.8.5'),\n  @Grab('org.neo4j:neo4j-graphql-java:{version}')\n])\n\nimport spark.*\nimport static spark.Spark.*\nimport com.google.gson.Gson\nimport org.neo4j.graphql.*\nimport org.neo4j.driver.v1.*\n\nschema = \"\"\"\ntype Person {\n  name: ID!\n  born: Int\n  actedIn: [Movie] @relation(name:\"ACTED_IN\")\n}\ntype Movie {\n  title: ID!\n  released: Int\n  tagline: String\n}\ntype Query {\n    person : [Person]\n}\n\"\"\"\n\ngson = new Gson()\nrender = (ResponseTransformer)gson.\u0026toJson\ndef query(value) { gson.fromJson(value,Map.class)[\"query\"] }\n\ngraphql = new Translator(SchemaBuilder.buildSchema(schema))\ndef translate(query) { graphql.translate(query) }\n\ndriver = GraphDatabase.driver(\"bolt://localhost\",AuthTokens.basic(\"neo4j\",\"s3cr3t\"))\ndef run(cypher) { driver.session().withCloseable {\n     it.run(cypher.query, Values.value(cypher.params)).list{ it.asMap() }}}\n\npost(\"/graphql\",\"application/json\", { req, res -\u003e  run(translate(query(req.body())).first()) }, render);\n----\n// include::docs/Server.groovy[]\n\nRun the example with:\n\n----\ngroovy docs/Server.groovy\n----\n\nand use http://localhost:4567/graphql as your GraphQL URL.\n\nIt uses a schema of:\n\n[source,graphql]\n----\ntype Person {\n  name: ID!\n  born: Int\n  actedIn: [Movie] @relation(name:\"ACTED_IN\")\n}\ntype Movie {\n  title: ID!\n  released: Int\n  tagline: String\n}\ntype Query {\n    person : [Person]\n}\n----\n\nAnd can run queries like:\n\n[source,graphql]\n----\n{\n  person(first:3) {\n    name\n    born\n    actedIn(first:2) {\n      title\n    }\n  }\n}\n----\n\nimage::docs/graphiql.jpg[]\n\nYou can also test it with `curl`\n\n----\ncurl -XPOST http://localhost:4567/graphql -d'{\"query\":\"{person {name}}\"}'\n----\n\nThis example doesn't handle introspection queries, but the one in the test directory does.\n\n== Advanced Queries\n\n.Filter, Sorting, Paging support\n----\n{\n  person(filter: {name_starts_with: \"L\"}, orderBy: \"born_asc\", first: 5, offset: 2) {\n    name\n    born\n    actedIn(first: 1) {\n      title\n    }\n  }\n}\n----\n\n----\n{\n  person(filter: {name_starts_with: \"J\", born_gte: 1970}, first:2) {\n    name\n    born\n    actedIn(first:1) {\n      title\n      released\n    }\n  }\n}\n----\n\n[[features]]\n== Features\n\n=== Current\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* 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* @cypher directive for top level queries and mutations, supports arguments\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* auto-generate mutation fields for all objects to create, update, delete\n* date(time)\n* interfaces\n* complex filter parameters, with optional query optimization strategy\n* scalars\n* spatial\n* skip limit params\n* sorting (nested)\n* ignoring fields\n\n=== Next\n\n* input types\n* unions\n\n== Documentation\n\n=== Parse SDL schema\n\n* Currently, schemas with object types, enums, fragments and Query types are parsed and handled.\n* `@relation` directives on fields and types for rich relationships\n* `@cypher` directives on fields and top-level query and mutation fields.\n* The configurable augmentation auto-generates queries and mutations (create,update,delete) for all types.\n* Supports the built-in scalars for GraphQL.\n* For arguments input types in many places and filters from GraphCool/Prisma.\n\n=== Resolve query Fields via Result Types\n\nFor _query fields_ that result in object types (even if wrapped in list/non-null), the appropriate object type is determined via the schema and used to translate the query.\n\ne.g.\n\n[source,graphql]\n----\ntype Query {\n  person: [Person]\n}\n# query \"person\" is resolved to and via \"Person\"\n\ntype Person {\n  name : String\n}\n----\n\n=== Neo4j 5.x support\n\nThis library supports queries for both neo4j `4.x` and `5.x`.\nBy default, the neo4j 5 dialect is enabled.\nThe dialect can be changed via `QueryContext`.\n\n.Example of changing the dialect via Translator\n[source,kotlin]\n----\nvar query\n    val ctx = QueryContext(neo4jDialect = Dialect.DEFAULT) //  Dialect.DEFAULT matches to neo4j version \u003c 5.x\n    query = translator.translate(query, params, ctx)\n----\n\n=== Handle Arguments as Equality Comparisons for Top Level and Nested Fields\n\nIf you add a simple argument to your top-level query or nested related fields, those will be translated to direct equality comparisons.\n\n[source,graphql]\n----\nperson(name:\"Joe\", age:42) {\n   name\n}\n----\n\nto an equivalent of\n\n[source,cypher]\n----\nMATCH (person:Person) WHERE person.name = 'Joe' AND person.age = 42 RETURN person { .name } AS person\n----\n\nThe literal values are turned into Cypher query parameters.\n\n=== Handle Relationships via @relation Directive on Schema Fields\n\nIf you want to represent a relationship from the graph in GraphQL you have to add a `@relation` directive which contains the relationship-type and the direction.\nThe default direction for a relationship is 'OUT'.\nOther values are 'IN' and 'BOTH'.\nSo you can use different domain names in your GraphQL fields that are independent of your graph model.\n\n[source,graphql]\n----\ntype Person {\n  name : String\n  actedIn: [Movie] @relation(name:\"ACTED_IN\", direction:OUT)\n}\n----\n\n[source,graphql]\n----\nperson(name:\"Keanu Reeves\") {\n  name\n  actedIn {\n    title\n  }\n}\n----\n\nNOTE: We use Neo4j's _pattern comprehensions_ to represent nested graph patterns in Cypher.\nThis will be updated to subqueries from 4.1\n\n=== Handle first, offset Arguments\n\nTo support pagination `first` is translated to `LIMIT` in Cypher and `offset` into `SKIP`\nFor nested queries these are converted into slices for arrays.\n\n[source,graphql]\n----\nperson(offset: 5, first:10) {\n  name\n}\n----\n\n[source,cypher]\n----\nMATCH (person:Person) RETURN person { .name }  AS person SKIP 5 LIMIT 10\n----\n\n=== Argument Types: string, int, float, array\n\nThe default Neo4j Cypher types are handled both as argument types as well as field types.\n\nNOTE: Spatial is not yet covered.\n\n=== Usage of ID\n\nEach type is expected to have exactly one filed of type `ID` defined.\nIf the field is named `_id`, it is interpreted as the database internal graph ID.\n\nSo there are 3 cases:\n\n.Case 1: Only the _ID_ field exists\n[source,graphql]\n----\ntype User {\n  email: ID!\n  name: String!\n}\n----\n\n.Case 2: Only the _ID_ field exists interpreted as internal ID\n[source,graphql]\n----\ntype User {\n  _id: ID!\n  email: String!\n  name: String!\n}\n----\n\n.Case 3: An _ID_ field exists but the internal ID is propagated as well\n[source,graphql]\n----\ntype User {\n  _id: Int!\n  email: ID!\n  name: String!\n}\n----\n\nIMPORTANT: For the auto generated queries and mutations the `ID` field is used as _primary key_.\n\nTIP: You should create a unique constraint on the `ID` fields\n\n=== Parameter Support\n\nGraphQL parameter's are passed onto Cypher, these are resolved correctly when used within the GraphQL query.\n\n=== Parametrization\n\nFor query injection prevention and caching purposes, literal values are translated into parameters.\n\n[source,graphql]\n----\nperson(name:\"Joe\", age:42, first:10) {\n   name\n}\n----\n\nto\n\n[source,cypher]\n----\nMATCH (person:Person)\nWHERE person.name = $personName AND person.age = $personAge\nRETURN person { .name } AS person\nLIMIT $first\n----\n\nThose parameters are returned as part of the `Cypher` type that's returned from the `translate()`-method.\n\n=== Aliases\n\nWe support query aliases, they are used as Cypher aliases too, so you get them back as keys in your result records.\n\nFor example:\n\n[source,graphql]\n----\nquery {\n  jane: person(name:\"Jane\") { name, age }\n  joe: person(name:\"Joe\") { name, age }\n}\n----\n\n=== Inline and Named Fragments\n\nThis is more of a technical feature, both types of fragments are resolved internally.\n\n=== Sorting (top-level)\n\nWe support sorting via an `orderBy` argument, which takes an Enum or String value of `fieldName_asc` or `fieldName_desc`.\n\n[source,graphql]\n----\nquery {\n  person(orderBy:[name_asc, age_desc]) {\n     name\n     age\n  }\n}\n----\n\n[source,cypher]\n----\nMATCH (person:Person)\nRETURN person { .name, .age } AS person\n\nORDER BY person.name ASC, person.age DESC\n----\n\nNOTE: We don't yet support ordering on nested relationship fields.\n\n=== Handle Rich Relationships via @relation Directive on Schema Types\n\nTo represent rich relationship types with properties, a `@relation` directive is supported on an object type.\n\nIn our example it would be the `Role` type.\n\n[source,graphql]\n----\ntype Role @relation(name:\"ACTED_IN\", from:\"actor\", to:\"movie\") {\n   actor: Person\n   movie: Movie\n   roles: [String]\n}\ntype Person {\n  name: String\n  born: Int\n  roles: [Role]\n}\ntype Movie {\n  title: String\n  released: Int\n  characters: [Role]\n}\n----\n\n[source,graphql]\n----\nperson(name:\"Keanu Reeves\") {\n   roles {\n      roles\n      movie {\n        title\n      }\n   }\n}\n----\n\n[[filters]]\n=== Filters\n\nFilters are a powerful way of selecting a subset of data.\nInspired by the https://www.graph.cool/docs/reference/graphql-api/query-api-nia9nushae[graph.cool/Prisma filter approach^], our filters work the same way.\n\nThese filters are documented in detail in the https://grandstack.io/docs/graphql-filtering [GRANDstack docs^].\n\nWe use nested input types for arbitrary filtering on query types and fields.\n\n[source,graphql]\n----\n{ Company(filter: { AND: { name_contains: \"Ne\", country_in [\"SE\"]}}) { name } }\n----\n\nYou can also apply nested filter on relations, which use suffixes like `(\"\",not,some, none, single, every)`\n\n[source,graphql]\n----\n{ Company(filter: {\n    employees_none { name_contains: \"Jan\"},\n    employees_some: { gender_in : [female]},\n    company_not: null })\n    {\n      name\n    }\n}\n----\n\n==== Optimized Filters\n\nIf you encounter performance problems with the cypher queries generated for the filter, you can activate an alternative algorithm using:\n\n[source,kotlin]\n----\nvar query\ntry {\n    val ctx = QueryContext(optimizedQuery = setOf(QueryContext.OptimizationStrategy.FILTER_AS_MATCH))\n    query = translator.translate(query, params, ctx)\n} catch (e: OptimizedQueryException) {\n    query = translator.translate(query, params)\n}\n----\n\nIf no query can be generated by the alternative algorithm, an `OptimizedQueryException` is thrown, so that a fallback to the actual algorithm can be used.\n\nlink:core/src/test/resources/optimized-query-for-filter.adoc[Examples of the alternative algorithm] can be seen in the tests.\n\n=== Inline and Named Fragments\n\nWe support inline and named fragments according to the GraphQL spec.\nMost of this is resolved on the parser/query side.\n\n.Named Fragment\n[source,graphql]\n----\nfragment details on Person { name, email, dob }\nquery {\n  person {\n    ...details\n  }\n}\n----\n\n.Inline Fragment\n[source,graphql]\n----\nquery {\n  person {\n    ... on Person { name, email, dob }\n  }\n}\n----\n\n=== @cypher Directives\n\nWith `@cypher` directives you can add the power of Cypher to your GraphQL API.\n\nIt allows you, without code to *compute field values* using complex queries.\n\nYou can also write your own, *custom top-level queries and mutations* using Cypher.\n\nArguments on the field are passed to the Cypher statement and can be used by name.\nThey must not be prefixed by `$` since they are no longer parameters.\nJust use the same name as the field's argument.\nThe current node is passed to the statement as `this`.\nThe statement should contain exactly one return expression without any alias.\n\nInput types are supported, they appear as `Map` type in your Cypher statement.\n\nNOTE: Those Cypher directive queries are only included in the generated Cypher statement if the field or query is included in the GraphQL query.\n\n==== On Fields\n\n.@cypher directive on a field\n[source,graphql]\n----\ntype Movie {\n  title: String\n  released: Int\n  similar(limit:Int=10): [Movie] @cypher(statement:\n        \"\"\"\n        MATCH (this)--\u003e(:Genre)\u003c--(sim)\n        WITH sim, count(*) as c ORDER BY c DESC LIMIT limit\n        RETURN sim\n        \"\"\")\n}\n----\n\nHere the `this`-variable is bound to the current movie.\nYou can use it to navigate the graph and collect data.\nThe `limit` variable is passed to the query as parameter.\n\n==== On Queries\n\nSimilarly, you can use the `@cypher` directive with a top-level query.\n\n.@cypher directive on query\n[source,graphql]\n----\ntype Query {\n   person(name:String) Person @cypher(\"MATCH (p:Person) WHERE p.name = name RETURN p\")\n}\n----\n\nYou can also return arrays from your query, the statements on query fields should be read-only queries.\n\n==== On Mutations\n\nYou can do the same for mutations, just with updating Cypher statements.\n\n.@cypher directive on mutation\n[source,graphql]\n----\ntype Mutation {\n   createPerson(name:String, age:Int) Person @cypher(\"CREATE (p:Person) SET p.name = name, p.age = age RETURN p\")\n}\n----\n\nYou can use more complex statements for creating these entities or even subgraphs.\n\nNOTE: The common CRUD mutations and queries are auto-generated, see below.\n\n=== Auto Generated Queries and Mutations\n\nTo reduce the amount of boilerplate code you have to write, we auto-generate generate top-level CRUD queries and mutations for all types.\n\nThis is configurable via the API, you can:\n\n* disable auto-generation (for mutations/queries)\n* disable per type\n* disable mutations per operation (create,delete,update)\n* configure capitalization of top level generated fields\n\nFor a schema like this:\n\n[source,graphql]\n----\ntype Person {\n   id:ID!\n   name: String\n   age: Int\n   movies: [Movie]\n}\n----\n\nIt would auto-generate quite a lot of things:\n\n* a query: `person(id:ID, name:String , age: Int, _id: Int, filter:_PersonFilter, orderBy:_PersonOrdering, first:Int, offset:Int) : [Person]`\n* a `_PersonOrdering` enum, for the `orderBy` argument with all fields for `_asc` and `_desc` sort order\n* a `_PersonInput` for creating Person objects\n* a `_PersonFilter` for the `filter` argument, which is a deeply nested input object (see \u003c\u003cfilters\u003e\u003e)\n* mutations for:\n** createPerson: `createPerson(id:ID!, name:String, age: Int) : Person`\n** mergePerson:  `mergePerson(id:ID!,  name:String, age:Int) : Person`\n** updatePerson: `updatePerson(id:ID!, name:String, age:Int) : Person`\n** deletePerson: `deletePerson(id:ID!) : Person`\n** addPersonMovies: `addPersonMovies(id:ID!,movies:[ID!]!) : Person`\n** deletePersonMovies: `deletePersonMovies(id:ID!,movies:[ID!]!) : Person`\n\nYou can then use those in your GraphQL queries like this:\n\n[source,graphql]\n----\nquery { person(age:42, orderBy:name_asc) {\n   id\n   name\n   age\n}\n----\n\nor\n\n[source,graphql]\n----\nmutation {\n  createPerson(id: \"34920n9qw0\", name:\"Jane Doe\", age:42) {\n    id\n    name\n    age\n  }\n}\n----\n\nYou find more examples in the link:core/src/test/resources/augmentation-tests.adoc[Augmentation Tests]\nand the link:core/src/test/resources/custom-fields.adoc[Custom queries and mutations Tests]\n\n== Build time schema augmentation\n\nSometimes you need the possibility to generate the augmented schema at compile time.\nTo achieve this, we provide a maven plugin which can be used as follows:\n\n[source,xml,subs=\"attributes,verbatim\"]\n----\n\u003cplugin\u003e\n    \u003cgroupId\u003eorg.neo4j\u003c/groupId\u003e\n    \u003cartifactId\u003eneo4j-graphql-augmented-schema-generator-maven-plugin\u003c/artifactId\u003e\n    \u003cversion\u003e{version}\u003c/version\u003e\n    \u003cexecutions\u003e\n        \u003cexecution\u003e\n            \u003cgoals\u003e\n                \u003cgoal\u003egenerate-schema\u003c/goal\u003e\n            \u003c/goals\u003e\n            \u003cconfiguration\u003e\n                \u003cschemaConfig\u003e \u003c!--1--\u003e\n                    \u003cpluralizeFields\u003etrue\u003c/pluralizeFields\u003e\n                    \u003cuseWhereFilter\u003etrue\u003c/useWhereFilter\u003e\n                    \u003cqueryOptionStyle\u003eINPUT_TYPE\u003c/queryOptionStyle\u003e\n                    \u003cmutation\u003e\n                        \u003cenabled\u003efalse\u003c/enabled\u003e\n                    \u003c/mutation\u003e\n                \u003c/schemaConfig\u003e\n                \u003coutputDirectory\u003e${project.build.directory}/augmented-schema\u003c/outputDirectory\u003e\n                \u003cfileset\u003e \u003c!--2--\u003e\n                    \u003cdirectory\u003e${project.basedir}/src/main/resources\u003c/directory\u003e\n                    \u003cinclude\u003e*.graphql\u003c/include\u003e\n                \u003c/fileset\u003e\n            \u003c/configuration\u003e\n        \u003c/execution\u003e\n    \u003c/executions\u003e\n\u003c/plugin\u003e\n----\n\n\u003c1\u003e Use the same configuration as for your SchemaBuilder\n\u003c2\u003e Define the source schema for which you want to have an augmented schema generated\n\nTake a look at the link:./examples/dgs-spring-boot/readme.adoc[spring boot dsg] example for a use case of this plugin, where it is used in combination with a code generator to have a type save graphql API\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneo4j-graphql%2Fneo4j-graphql-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneo4j-graphql%2Fneo4j-graphql-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneo4j-graphql%2Fneo4j-graphql-java/lists"}