From 390d5888611751710d79dfb41fd8ad3c390b77bd Mon Sep 17 00:00:00 2001 From: Lidia Zuin <102308961+lidiazuin@users.noreply.github.com> Date: Fri, 15 Sep 2023 11:12:11 +0200 Subject: [PATCH 01/13] Add page-aliases for version 4 (#31) (#32) Co-authored-by: Neil Dewhurst --- modules/ROOT/pages/migration/authorization.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/ROOT/pages/migration/authorization.adoc b/modules/ROOT/pages/migration/authorization.adoc index 561b6f04..2ab125de 100644 --- a/modules/ROOT/pages/migration/authorization.adoc +++ b/modules/ROOT/pages/migration/authorization.adoc @@ -1,6 +1,10 @@ = Authentication and Authorization +<<<<<<< HEAD:modules/ROOT/pages/migration/authorization.adoc :description: This page describes the changes in authentication and authorization features in version 4.0.0 of the Neo4j GraphQL Library. :page-aliases: auth/global-authentication.adoc, migration/v4-migration/authorization.adoc +======= +:page-aliases: auth/global-authentication.adoc +>>>>>>> e533fd8 (Add page-aliases for version 4 (#31) (#32)):modules/ROOT/pages/migration/v4-migration/authorization.adoc The largest breaking change in version 4.0.0 is the removal of the `@auth` directive, which requires a migration to the new `@authentication`, `@authorization`, and `@subscriptionsAuthorization` directives. From 5c9e7cbbd9caa4c14097e76a96f87971d778ab1f Mon Sep 17 00:00:00 2001 From: Lidia Zuin <102308961+lidiazuin@users.noreply.github.com> Date: Tue, 19 Sep 2023 12:27:14 +0200 Subject: [PATCH 02/13] Editorial review of the latest additions (#34) * Update publish.yml * Editorial review of the most recent changes * reverting changes to partials * fixing note formatting * Add page-aliases for version 4 (#31) (#32) Co-authored-by: Neil Dewhurst * Editorial review of the most recent changes * fixing note formatting * Add page-aliases for version 4 (#31) (#32) Co-authored-by: Neil Dewhurst * Editorial review of the most recent changes * fixing note formatting * Add page-aliases for version 4 (#31) (#32) Co-authored-by: Neil Dewhurst * Editorial review of the most recent changes * Add page-aliases for version 4 (#31) * revert * Apply suggestions from code review Co-authored-by: Michael Webb <28074382+mjfwebb@users.noreply.github.com> --------- Co-authored-by: Neil Dewhurst Co-authored-by: Michael Webb <28074382+mjfwebb@users.noreply.github.com> --- .../ROOT/pages/authentication-and-authorization/index.adoc | 4 ++-- modules/ROOT/pages/migration/authorization.adoc | 4 ---- modules/ROOT/pages/subscriptions/events.adoc | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/modules/ROOT/pages/authentication-and-authorization/index.adoc b/modules/ROOT/pages/authentication-and-authorization/index.adoc index de1e16d7..f51c7a3e 100644 --- a/modules/ROOT/pages/authentication-and-authorization/index.adoc +++ b/modules/ROOT/pages/authentication-and-authorization/index.adoc @@ -6,10 +6,10 @@ auth/authorization/allow.adoc, auth/authorization/bind.adoc, auth/authorization/ auth/authorization/where.adoc, guides/v4-migration/authorization.adoc [WARNING] -==== +=== The `@auth` directive has been replaced by `@authentication` and `@authorization`. See the xref::migration/v4-migration/authorization.adoc[Migration guide] for details on how to upgrade. -==== +=== * xref::authentication-and-authorization/authentication.adoc[Authentication] - Explicit authentication, configured using the `@authentication` directive. * xref::authentication-and-authorization/authorization.adoc[Authorization] - Authorization rules set using the `@authorization` directive. diff --git a/modules/ROOT/pages/migration/authorization.adoc b/modules/ROOT/pages/migration/authorization.adoc index 2ab125de..561b6f04 100644 --- a/modules/ROOT/pages/migration/authorization.adoc +++ b/modules/ROOT/pages/migration/authorization.adoc @@ -1,10 +1,6 @@ = Authentication and Authorization -<<<<<<< HEAD:modules/ROOT/pages/migration/authorization.adoc :description: This page describes the changes in authentication and authorization features in version 4.0.0 of the Neo4j GraphQL Library. :page-aliases: auth/global-authentication.adoc, migration/v4-migration/authorization.adoc -======= -:page-aliases: auth/global-authentication.adoc ->>>>>>> e533fd8 (Add page-aliases for version 4 (#31) (#32)):modules/ROOT/pages/migration/v4-migration/authorization.adoc The largest breaking change in version 4.0.0 is the removal of the `@auth` directive, which requires a migration to the new `@authentication`, `@authorization`, and `@subscriptionsAuthorization` directives. diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index 644da9fb..7908600f 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -41,7 +41,7 @@ Changes made directly to the database or using the xref::type-definitions/direct == `CREATE` Subscriptions to `CREATE` events listen *only* to newly created nodes, not new relationships. -In this occasion, a new event is triggered for each new node, containing its properties. +In this case, a new event is triggered for each new node, containing its properties. This action is performed with the top-level subscription `[type]Created`, which contains the following fields: From af99faaf8f156789ff2d71401882d780b014d0d4 Mon Sep 17 00:00:00 2001 From: Lidia Zuin <102308961+lidiazuin@users.noreply.github.com> Date: Tue, 26 Sep 2023 14:46:56 +0200 Subject: [PATCH 03/13] Fix scalar description placeholders #38 (#39) * Editorial review of the most recent changes * reverting changes to partials * fixing note formatting * Add page-aliases for version 4 (#31) (#32) Co-authored-by: Neil Dewhurst * Editorial review of the most recent changes * fixing note formatting * Editorial review of the most recent changes * fixing note formatting * Add page-aliases for version 4 (#31) (#32) Co-authored-by: Neil Dewhurst * Editorial review of the most recent changes * Fix scalar description placeholders (#38) --------- Co-authored-by: Neil Dewhurst Co-authored-by: Darrell Warde <8117355+darrellwarde@users.noreply.github.com> --- .../ROOT/pages/authentication-and-authorization/index.adoc | 4 ++-- modules/ROOT/pages/subscriptions/events.adoc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ROOT/pages/authentication-and-authorization/index.adoc b/modules/ROOT/pages/authentication-and-authorization/index.adoc index f51c7a3e..de1e16d7 100644 --- a/modules/ROOT/pages/authentication-and-authorization/index.adoc +++ b/modules/ROOT/pages/authentication-and-authorization/index.adoc @@ -6,10 +6,10 @@ auth/authorization/allow.adoc, auth/authorization/bind.adoc, auth/authorization/ auth/authorization/where.adoc, guides/v4-migration/authorization.adoc [WARNING] -=== +==== The `@auth` directive has been replaced by `@authentication` and `@authorization`. See the xref::migration/v4-migration/authorization.adoc[Migration guide] for details on how to upgrade. -=== +==== * xref::authentication-and-authorization/authentication.adoc[Authentication] - Explicit authentication, configured using the `@authentication` directive. * xref::authentication-and-authorization/authorization.adoc[Authorization] - Authorization rules set using the `@authorization` directive. diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index 7908600f..644da9fb 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -41,7 +41,7 @@ Changes made directly to the database or using the xref::type-definitions/direct == `CREATE` Subscriptions to `CREATE` events listen *only* to newly created nodes, not new relationships. -In this case, a new event is triggered for each new node, containing its properties. +In this occasion, a new event is triggered for each new node, containing its properties. This action is performed with the top-level subscription `[type]Created`, which contains the following fields: From dd24194fb4a74e1f573c284234a85c35782f9f24 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Tue, 5 Sep 2023 15:34:54 +0200 Subject: [PATCH 04/13] Editorial review of the most recent changes --- modules/ROOT/pages/authentication-and-authorization/index.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/authentication-and-authorization/index.adoc b/modules/ROOT/pages/authentication-and-authorization/index.adoc index de1e16d7..833024ed 100644 --- a/modules/ROOT/pages/authentication-and-authorization/index.adoc +++ b/modules/ROOT/pages/authentication-and-authorization/index.adoc @@ -1,4 +1,4 @@ -= Authentication and Authorization += Authentication and authorization :description: This section covers authentication andd authorization features in the Neo4j GraphQL Library. :page-aliases: auth/index.adoc, auth/setup.adoc, auth/authentication.adoc, \ auth/authorization.adoc, auth/auth-directive.adoc, auth/subscriptions.adoc, \ From fdb301fe3f9cdfa921d32495250ba2864fb63e59 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Wed, 6 Sep 2023 11:04:34 +0200 Subject: [PATCH 05/13] reverting changes to partials --- modules/ROOT/partials/reusing-content.adoc | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/ROOT/partials/reusing-content.adoc b/modules/ROOT/partials/reusing-content.adoc index 52df337f..464c8ddc 100644 --- a/modules/ROOT/partials/reusing-content.adoc +++ b/modules/ROOT/partials/reusing-content.adoc @@ -1,2 +1 @@ -[[include-typescript]] This paragraph can be used anywhere with the syntax shown in xref:content-types.adoc#_partials[]. \ No newline at end of file From 12f27ae121abb9c86c314522b0345e0f2ca8af60 Mon Sep 17 00:00:00 2001 From: Lidia Zuin <102308961+lidiazuin@users.noreply.github.com> Date: Fri, 15 Sep 2023 11:12:11 +0200 Subject: [PATCH 06/13] Add page-aliases for version 4 (#31) (#32) Co-authored-by: Neil Dewhurst --- .../index.adoc | 2 +- .../pages/reference/directives/cypher.adoc | 229 ++++++++++++++++++ .../pages/reference/directives/index.adoc | 161 ++++++++++++ .../type-configuration.adoc | 156 ++++++++++++ .../type-definitions/interfaces.adoc | 135 +++++++++++ modules/ROOT/pages/subscriptions/events.adoc | 31 +-- 6 files changed, 685 insertions(+), 29 deletions(-) create mode 100644 modules/ROOT/pages/reference/directives/cypher.adoc create mode 100644 modules/ROOT/pages/reference/directives/index.adoc create mode 100644 modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc create mode 100644 modules/ROOT/pages/reference/type-definitions/interfaces.adoc diff --git a/modules/ROOT/pages/authentication-and-authorization/index.adoc b/modules/ROOT/pages/authentication-and-authorization/index.adoc index 833024ed..de1e16d7 100644 --- a/modules/ROOT/pages/authentication-and-authorization/index.adoc +++ b/modules/ROOT/pages/authentication-and-authorization/index.adoc @@ -1,4 +1,4 @@ -= Authentication and authorization += Authentication and Authorization :description: This section covers authentication andd authorization features in the Neo4j GraphQL Library. :page-aliases: auth/index.adoc, auth/setup.adoc, auth/authentication.adoc, \ auth/authorization.adoc, auth/auth-directive.adoc, auth/subscriptions.adoc, \ diff --git a/modules/ROOT/pages/reference/directives/cypher.adoc b/modules/ROOT/pages/reference/directives/cypher.adoc new file mode 100644 index 00000000..390d1351 --- /dev/null +++ b/modules/ROOT/pages/reference/directives/cypher.adoc @@ -0,0 +1,229 @@ +[[type-definitions-cypher]] += `@cypher` directive +:page-aliases: type-definitions/cypher.adoc + +The `@cypher` directive binds a GraphQL field to the result(s) of a Cypher query. + +This directive can be used both for properties in a type or as top level queries: + +== Definition + +[source, graphql, indent=0] +---- +"""Instructs @neo4j/graphql to run the specified Cypher statement in order to resolve the value of the field to which the directive is applied.""" +directive @cypher( + """The Cypher statement to run which returns a value of the same type composition as the field definition on which the directive is applied.""" + statement: String!, + """Name of the returned variable from the Cypher statement.""" + columnName: String! +) on FIELD_DEFINITION +---- + + +== Globals + +Global variables are available for use within the Cypher statement. + +=== `this` + +The value `this` is a reference to the currently resolved node, and it can be used to traverse the graph. + +This can be seen in the usage example xref::/type-definitions/directives/cypher.adoc#type-definitions-cypher-object-usage[On an object type field] below. + +=== `auth` + +The value `auth` is represented by the following TypeScript interface definition: + +[source, typescript, indent=0] +---- +interface Auth { + isAuthenticated: boolean; + roles?: string[]; + jwt: any; +} +---- + +For example, you could use the JWT in the request to return the value of the currently logged in User: + +[source, graphql, indent=0] +---- +type User { + id: String +} + +type Query { + me: User @cypher( + statement: """ + MATCH (user:User {id: $jwt.sub}) + RETURN user + """, + columnName: "user" + ) +} +---- + + +=== `cypherParams` +Use to inject values into the cypher query from the GraphQL context function. + +Inject into context: + +[source, typescript, indent=0] +---- +const server = new ApolloServer({ + typeDefs, +}); + +await startStandaloneServer(server, { + context: async ({ req }) => ({ cypherParams: { userId: "user-id-01" } }), +}); +---- + +Use in cypher query: + +[source, graphql, indent=0] +---- +type Query { + userPosts: [Post] @cypher(statement: """ + MATCH (:User {id: $userId})-[:POSTED]->(p:Post) + RETURN p + """, columnName: "p") +} +---- + +== Return values + +The return value of the Cypher statement must be of the same type to which the directive is applied. + +The variable should also be aliased with a name that must be the same as the named passed to `columnName`, this can be the name of a node or relationship query or an alias in the `RETURN` statement of the cypher. + +=== Scalar values + +The Cypher statement must return a value which matches the scalar type to which the directive was applied. + +[source, graphql, indent=0] +---- +type Query { + randomNumber: Int @cypher(statement: "RETURN rand() as result", columnName: "result") +} +---- + +=== Object types + +When returning an object type, all fields of the type must be available in the Cypher return value. This can be achieved by either returning the entire object from the Cypher query, or returning a map of the fields which are required for the object type. Both approaches are demonstrated below: + +[source, graphql, indent=0] +---- +type User { + id +} + +type Query { + users: [User] + @cypher( + statement: """ + MATCH (u:User) + RETURN u + """, + columnName: "u" + ) +} +---- + +[source, graphql, indent=0] +---- +type User { + id +} + +type Query { + users: [User] @cypher(statement: """ + MATCH (u:User) + RETURN { + id: u.id + } as result + """, columnName: "result") +} +---- + +The downside of the latter approach is that you will need to adjust the return object as you change your object type definition. + +== Usage examples + +[[type-definitions-cypher-object-usage]] +=== On an object type field + +In the example below, a field `similarMovies` is bound to the `Movie` type, to find other movies with an overlap of actors: + +[source, graphql, indent=0] +---- +type Actor { + actorId: ID! + name: String + movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) +} + +type Movie { + movieId: ID! + title: String + description: String + year: Int + actors(limit: Int = 10): [Actor!]! + @relationship(type: "ACTED_IN", direction: IN) + similarMovies(limit: Int = 10): [Movie] + @cypher( + statement: """ + MATCH (this)<-[:ACTED_IN]-(:Actor)-[:ACTED_IN]->(rec:Movie) + WITH rec, COUNT(*) AS score ORDER BY score DESC + RETURN rec LIMIT $limit + """, + columnName: "rec" + ) +} +---- + +=== On a query type field + +The example below demonstrates a simple query to return all of the actors in the database: + +[source, graphql, indent=0] +---- +type Actor { + actorId: ID! + name: String +} + +type Query { + allActors: [Actor] + @cypher( + statement: """ + MATCH (a:Actor) + RETURN a + """, + columnName: "a" + ) +} +---- + +=== On a mutation type field + +The example below demonstrates a simple mutation using a Cypher query to insert a single actor with the specified name argument: + +[source, graphql, indent=0] +---- +type Actor { + actorId: ID! + name: String +} + +type Mutation { + createActor(name: String!): Actor + @cypher( + statement: """ + CREATE (a:Actor {name: $name}) + RETURN a + """, + columnName: "a" + ) +} +---- \ No newline at end of file diff --git a/modules/ROOT/pages/reference/directives/index.adoc b/modules/ROOT/pages/reference/directives/index.adoc new file mode 100644 index 00000000..89535425 --- /dev/null +++ b/modules/ROOT/pages/reference/directives/index.adoc @@ -0,0 +1,161 @@ +[[directives]] += Directives +:page-aliases: directives.adoc + +== `@alias` + +The `@alias` directive will map a GraphQL schema field to a Neo4j property on a node or relationship. + +Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-alias[`@alias`] + +== `@coalesce` + +The `@coalesce` directive exposes a mechanism for querying against non-existent, `null` values on a node. + +Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-coalesce[`@coalesce`] + +[[custom-resolver-directive]] +== `@customResolver` + +The `@customResolver` directive specifies that a field will be resolved by a custom resolver, and allows the specification +of any required fields that will be passed as arguments to the custom resolver. + +Reference: xref::custom-resolvers.adoc#custom-resolver-directive[`@customResolver`] + +== `@cypher` + +The `@cypher` directive overrides field resolution (including `Query` and `Mutation` fields), instead resolving with the specified Cypher. + +Reference: xref::/type-definitions/directives/cypher.adoc[`@cypher` directive] + +== `@default` + +The `@default` directive allows for the setting of a default value for a field on object creation. + +Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-default[`@default`] + +== `@exclude` label:deprecated[] + +This directive is deprecated. + +Use the xref:schema-configuration/type-configuration.adoc#_query[`@query`], xref:schema-configuration/type-configuration.adoc#_mutation[`@mutation`] and the xref:schema-configuration/type-configuration.adoc#_subscription[`@subscription`] directives instead. + +The `@exclude` directive is used on object types to instruct them to be skipped during Query, Mutation and Subscription generation. + +Reference: xref::schema-configuration/type-configuration.adoc#_exclude_deprecated[`@exclude`] + +== `@filterable` + +The `@filterable` directive defines the filters generated for a field. + +Reference: xref:schema-configuration/field-configuration.adoc#_filterable[`@filterable`] + +== `@fulltext` + +The `@fulltext` directive indicates that there should be a Fulltext index inserted into the database for the specified Node and its properties. + +Reference: xref::/type-definitions/directives/indexes-and-constraints.adoc#type-definitions-indexes-fulltext[Fulltext indexes] + +== `@id` + +The `@id` directive marks a field as the unique ID for an object type, and allows for autogeneration of IDs. + +Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-id[`@id`] + +== `@limit` + +The `@limit` is to be used on nodes, and when applied will inject values into Cypher `LIMIT` clauses. + +Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-limit[`@limit`] + +== `@mutation` + +This directive is used to limit the availability of Mutation operations in the library. + +Reference: xref:schema-configuration/type-configuration.adoc#_mutation[`@mutation`] + +== `@node` + +The `@node` directive is used to specify the configuration of a GraphQL object type which represents a Neo4j node. + +Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-node[`@node`] + +[[plural-directive]] +== `@plural` + +The `@plural` directive redefines how to compose the plural of the type for the generated operations. +This is particularly useful for types that are not correctly pluralized or are non-English words. + +Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-plural[`@plural`] + +[[populated-by-directive]] +== `@populatedBy` + +The `@populatedBy` directive is used to specify a callback function that gets executed during GraphQL query parsing, +to populate fields which have not been provided within the input. + +Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-populated-by[`@populatedBy`] + +== `@private` + +The `@private` directive protects fields which should only be available through the xref::ogm/index.adoc[OGM]. + +Reference: xref::ogm/private.adoc[`@private` Directive] + +== `@query` + +This directive is used to limit the availability of Query operations in the library. + +Reference: xref:schema-configuration/type-configuration.adoc#_query[`@query`] + +== `@relationship` + +The `@relationship` directive is used to configure relationships between object types. + +Reference: xref::/type-definitions/types/relationships.adoc[Relationships], xref::schema-configuration/field-configuration.adoc#_relationship[`@relationship`] + +== `@relationshipProperties` + +Required to help you distinguish between interfaces which are used for relationship properties, and otherwise. + +Can only be used on interfaces, as per its definition: + +[source, graphql, indent=0] +---- +"""Required to differentiate between interfaces for relationship properties, and otherwise.""" +directive @relationshipProperties on INTERFACE +---- + +== `@relayId` + +The `@relayId` directive can be used on object type fields, to flag which field should be used as the global node identifier for Relay. Can be used once per type. The use of the `@relayId` directive ensures a unique node property constraint for the field. + +== `@selectable` + +The `@selectable` directive sets the availability of fields on queries and aggregations. + +Reference: xref:schema-configuration/field-configuration.adoc#_selectable[`@selectable`] + +== `@settable` + +The `@settable` directive sets the availability of fields on the create and update inputs. + +Reference: xref:schema-configuration/field-configuration.adoc#_settable[`@settable`] + +== `@subscription` + +This directive is used to limit Subscription events available in the library. + +Reference: xref:schema-configuration/type-configuration.adoc#_subscription[`@subscription`] + +== `@timestamp` + +The `@timestamp` directive flags fields to be used to store timestamps on create/update events. + +Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-timestamp[`@timestamp`] + +== `@unique` + +The `@unique` directive indicates that there should be a uniqueness constraint in the database for the fields that it is applied to. + +Reference: xref::/type-definitions/directives/indexes-and-constraints.adoc#type-definitions-constraints-unique[Unique node property constraints] diff --git a/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc b/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc new file mode 100644 index 00000000..0d0a5e46 --- /dev/null +++ b/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc @@ -0,0 +1,156 @@ +[[schema-configuration-type-configuration]] += Type Configuration + + +When representing a Neo4j Node, a GraphQL Object type produces multiple operation fields in the `Query`, `Mutation`, and `Subscription` types. +For example: + +[source, graphql, indent=0] +---- +type Movie { + title: String + length: Int +} +---- + +From these type definitions, the library generates the following operation fields: + +**Query**: + + * `movies` + * `moviesAggregate` + * `moviesConnection` + +**Mutation**: + + * `createMovies` + * `deleteMovies` + * `updateMovies` + +**Subscription**: + + * `movieCreated` + * `movieUpdated` + * `movieDeleted` +. + +This section explains how to reduce the operation fields produced using the directives `@query`, `@mutation`, and `@subscription`. + +== `@query` + +This directive is used to limit the availability of query operations in the library. + +=== Definition + +[source, graphql, indent=0] +---- +directive @query(read: Boolean! = true, aggregate: Boolean! = false) on OBJECT | SCHEMA +---- + +[NOTE] +==== +Aggregations will no longer be generated by default in the 4.0.0 version of the library. +See xref:migration/v4-migration/index.adoc#opt-in-aggregation[`Opt-in Aggregation`] for more information. +==== + +=== Usage + +==== Disable _movies_ and _moviesConnection_ operations + +[source, graphql, indent=0] +---- +type Movie @query(read: false, aggregate: true) { + title: String + length: Int +} +---- + +==== Disable _moviesAggregate_ operations + +[source, graphql, indent=0] +---- +type Movie @query(read: true, aggregate: false) { + title: String + length: Int +} +---- + +== `@mutation` + +This directive is used to limit the availability of Mutation operations in the library. + +=== Definition + +[source, graphql, indent=0] +---- +enum MutationFields { + CREATE + UPDATE + DELETE +} + +directive @mutation(operations: [MutationFields!]! = [CREATE, UPDATE, DELETE]) on OBJECT | SCHEMA +---- + +=== Usage + +==== Disable Create, Delete, and Update operations for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @mutation(operations: []) { + title: String + length: Int +} +---- + +==== Enable only Create operations for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @mutation(operations: [CREATE]) { + title: String + length: Int +} +---- + +== `@subscription` + +This directive is used to limit Subscription operations in the library. + +=== Definition + +[source, graphql, indent=0] +---- +enum SubscriptionEvent { + CREATED + UPDATED + DELETED + RELATIONSHIP_CREATED + RELATIONSHIP_DELETED +} + +directive @subscription(events: [SubscriptionEvent!]! = [CREATED, UPDATED, DELETED, RELATIONSHIP_CREATED, RELATIONSHIP_DELETED]) on OBJECT | SCHEMA +---- + +=== Usage + +==== Disable subscriptions for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @subscription(events: []) { + title: String + length: Int +} +---- + +==== Enable only _movieCreated_ subscription for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @subscription(events: [CREATED]) { + title: String + length: Int +} +---- diff --git a/modules/ROOT/pages/reference/type-definitions/interfaces.adoc b/modules/ROOT/pages/reference/type-definitions/interfaces.adoc new file mode 100644 index 00000000..adc72a27 --- /dev/null +++ b/modules/ROOT/pages/reference/type-definitions/interfaces.adoc @@ -0,0 +1,135 @@ +[[schema-configuration-type-configuration]] += Type Configuration + + +When representing a Neo4j Node, a GraphQL Object type produces multiple operation fields in the `Query`, `Mutation`, and `Subscription` types. +For example: + +[source, graphql, indent=0] +---- +type Movie { + title: String + length: Int +} +---- + +From these type definitions, the library generates the following operation fields: + +**Query**: + + * `movies` + * `moviesAggregate` + * `moviesConnection` + +**Mutation**: + + * `createMovies` + * `deleteMovies` + * `updateMovies` + +**Subscription**: + + * `movieCreated` + * `movieUpdated` + * `movieDeleted` +. + +This section explains how to reduce the operation fields produced using the directives `@query`, `@mutation`, and `@subscription`. + +== `@query` + +This directive is used to limit the availability of query operations in the library. + +=== Definition + +[source, graphql, indent=0] +---- +directive @query(read: Boolean! = true, aggregate: Boolean! = false) on OBJECT | SCHEMA +---- + +[NOTE] +==== +Aggregations will no longer be generated by default in the 4.0.0 version of the library. +See xref:migration/v4-migration/index.adoc#opt-in-aggregation[`Opt-in Aggregation`] for more information. +==== + +[[type-definitions-interfaced-types-querying]] +== Querying an interface + +Which implementations are returned by a query are dictated by the `where` filter applied. + +For example, the following will return all productions with title starting "The " for every actor: + +[source, graphql, indent=0] +---- +enum MutationFields { + CREATE + UPDATE + DELETE +} + +directive @mutation(operations: [MutationFields!]! = [CREATE, UPDATE, DELETE]) on OBJECT | SCHEMA +---- + +=== Usage + +==== Disable Create, Delete, and Update operations for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @mutation(operations: []) { + title: String + length: Int +} +---- + +==== Enable only Create operations for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @mutation(operations: [CREATE]) { + title: String + length: Int +} +---- + +== `@subscription` + +This directive is used to limit Subscription operations in the library. + +=== Definition + +[source, graphql, indent=0] +---- +enum SubscriptionFields { + CREATE + UPDATE + DELETE + CREATE_RELATIONSHIP + DELETE_RELATIONSHIP +} + +directive @subscription(operations: [SubscriptionFields!]! = [CREATE, UPDATE, DELETE, CREATE_RELATIONSHIP, DELETE_RELATIONSHIP]) on OBJECT | SCHEMA +---- + +=== Usage + +==== Disable subscriptions for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @subscription(operations: []) { + title: String + length: Int +} +---- + +==== Enable only _movieCreated_ subscription for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @subscription(operations: [CREATE]) { + title: String + length: Int +} +---- \ No newline at end of file diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index 644da9fb..d0a856de 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -8,35 +8,10 @@ subscriptions/events/update.adoc This page covers a variety of subscription options offered by the Neo4j GraphQL Library. [NOTE] -=== +==== Only changes made through `@neo4j/graphql` should trigger the events here described. -Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. -=== - -== `CREATE` - -Subscriptions to `CREATE` events listen *only* to newly created nodes, not new relationships. -In this occasion, a new event is triggered for each new node, containing its properties. - -This action is performed with the top-level subscription `[type]Created`, which contains the following fields: - -* `event`: the event triggering this subscription (in this case, `CREATE`). -* `created`: top-level properties of the newly created node, without relationships. -* `timestamp`: the timestamp in which the mutation was made. -If a same query triggers multiple events, they should have the same timestamp. - -As an example, consider the following type definitions: - -[source,graphql,indent=0] ----- -type Movie { - title: String - genre: String -} ----- - -Note, however, that only changes made through `@neo4j/graphql` should trigger events. -Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. +Changes made directly to the database or using the xref::reference/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. +==== == `CREATE` From 587994f43b4c9c0a98f6cd2edbefb8c24def726e Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Tue, 5 Sep 2023 15:34:54 +0200 Subject: [PATCH 07/13] Editorial review of the most recent changes --- .../pages/reference/directives/cypher.adoc | 229 ------------------ .../pages/reference/directives/index.adoc | 161 ------------ .../type-configuration.adoc | 156 ------------ .../type-definitions/interfaces.adoc | 135 ----------- modules/ROOT/pages/subscriptions/events.adoc | 29 ++- modules/ROOT/partials/reusing-content.adoc | 1 + 6 files changed, 28 insertions(+), 683 deletions(-) delete mode 100644 modules/ROOT/pages/reference/directives/cypher.adoc delete mode 100644 modules/ROOT/pages/reference/directives/index.adoc delete mode 100644 modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc delete mode 100644 modules/ROOT/pages/reference/type-definitions/interfaces.adoc diff --git a/modules/ROOT/pages/reference/directives/cypher.adoc b/modules/ROOT/pages/reference/directives/cypher.adoc deleted file mode 100644 index 390d1351..00000000 --- a/modules/ROOT/pages/reference/directives/cypher.adoc +++ /dev/null @@ -1,229 +0,0 @@ -[[type-definitions-cypher]] -= `@cypher` directive -:page-aliases: type-definitions/cypher.adoc - -The `@cypher` directive binds a GraphQL field to the result(s) of a Cypher query. - -This directive can be used both for properties in a type or as top level queries: - -== Definition - -[source, graphql, indent=0] ----- -"""Instructs @neo4j/graphql to run the specified Cypher statement in order to resolve the value of the field to which the directive is applied.""" -directive @cypher( - """The Cypher statement to run which returns a value of the same type composition as the field definition on which the directive is applied.""" - statement: String!, - """Name of the returned variable from the Cypher statement.""" - columnName: String! -) on FIELD_DEFINITION ----- - - -== Globals - -Global variables are available for use within the Cypher statement. - -=== `this` - -The value `this` is a reference to the currently resolved node, and it can be used to traverse the graph. - -This can be seen in the usage example xref::/type-definitions/directives/cypher.adoc#type-definitions-cypher-object-usage[On an object type field] below. - -=== `auth` - -The value `auth` is represented by the following TypeScript interface definition: - -[source, typescript, indent=0] ----- -interface Auth { - isAuthenticated: boolean; - roles?: string[]; - jwt: any; -} ----- - -For example, you could use the JWT in the request to return the value of the currently logged in User: - -[source, graphql, indent=0] ----- -type User { - id: String -} - -type Query { - me: User @cypher( - statement: """ - MATCH (user:User {id: $jwt.sub}) - RETURN user - """, - columnName: "user" - ) -} ----- - - -=== `cypherParams` -Use to inject values into the cypher query from the GraphQL context function. - -Inject into context: - -[source, typescript, indent=0] ----- -const server = new ApolloServer({ - typeDefs, -}); - -await startStandaloneServer(server, { - context: async ({ req }) => ({ cypherParams: { userId: "user-id-01" } }), -}); ----- - -Use in cypher query: - -[source, graphql, indent=0] ----- -type Query { - userPosts: [Post] @cypher(statement: """ - MATCH (:User {id: $userId})-[:POSTED]->(p:Post) - RETURN p - """, columnName: "p") -} ----- - -== Return values - -The return value of the Cypher statement must be of the same type to which the directive is applied. - -The variable should also be aliased with a name that must be the same as the named passed to `columnName`, this can be the name of a node or relationship query or an alias in the `RETURN` statement of the cypher. - -=== Scalar values - -The Cypher statement must return a value which matches the scalar type to which the directive was applied. - -[source, graphql, indent=0] ----- -type Query { - randomNumber: Int @cypher(statement: "RETURN rand() as result", columnName: "result") -} ----- - -=== Object types - -When returning an object type, all fields of the type must be available in the Cypher return value. This can be achieved by either returning the entire object from the Cypher query, or returning a map of the fields which are required for the object type. Both approaches are demonstrated below: - -[source, graphql, indent=0] ----- -type User { - id -} - -type Query { - users: [User] - @cypher( - statement: """ - MATCH (u:User) - RETURN u - """, - columnName: "u" - ) -} ----- - -[source, graphql, indent=0] ----- -type User { - id -} - -type Query { - users: [User] @cypher(statement: """ - MATCH (u:User) - RETURN { - id: u.id - } as result - """, columnName: "result") -} ----- - -The downside of the latter approach is that you will need to adjust the return object as you change your object type definition. - -== Usage examples - -[[type-definitions-cypher-object-usage]] -=== On an object type field - -In the example below, a field `similarMovies` is bound to the `Movie` type, to find other movies with an overlap of actors: - -[source, graphql, indent=0] ----- -type Actor { - actorId: ID! - name: String - movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) -} - -type Movie { - movieId: ID! - title: String - description: String - year: Int - actors(limit: Int = 10): [Actor!]! - @relationship(type: "ACTED_IN", direction: IN) - similarMovies(limit: Int = 10): [Movie] - @cypher( - statement: """ - MATCH (this)<-[:ACTED_IN]-(:Actor)-[:ACTED_IN]->(rec:Movie) - WITH rec, COUNT(*) AS score ORDER BY score DESC - RETURN rec LIMIT $limit - """, - columnName: "rec" - ) -} ----- - -=== On a query type field - -The example below demonstrates a simple query to return all of the actors in the database: - -[source, graphql, indent=0] ----- -type Actor { - actorId: ID! - name: String -} - -type Query { - allActors: [Actor] - @cypher( - statement: """ - MATCH (a:Actor) - RETURN a - """, - columnName: "a" - ) -} ----- - -=== On a mutation type field - -The example below demonstrates a simple mutation using a Cypher query to insert a single actor with the specified name argument: - -[source, graphql, indent=0] ----- -type Actor { - actorId: ID! - name: String -} - -type Mutation { - createActor(name: String!): Actor - @cypher( - statement: """ - CREATE (a:Actor {name: $name}) - RETURN a - """, - columnName: "a" - ) -} ----- \ No newline at end of file diff --git a/modules/ROOT/pages/reference/directives/index.adoc b/modules/ROOT/pages/reference/directives/index.adoc deleted file mode 100644 index 89535425..00000000 --- a/modules/ROOT/pages/reference/directives/index.adoc +++ /dev/null @@ -1,161 +0,0 @@ -[[directives]] -= Directives -:page-aliases: directives.adoc - -== `@alias` - -The `@alias` directive will map a GraphQL schema field to a Neo4j property on a node or relationship. - -Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-alias[`@alias`] - -== `@coalesce` - -The `@coalesce` directive exposes a mechanism for querying against non-existent, `null` values on a node. - -Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-coalesce[`@coalesce`] - -[[custom-resolver-directive]] -== `@customResolver` - -The `@customResolver` directive specifies that a field will be resolved by a custom resolver, and allows the specification -of any required fields that will be passed as arguments to the custom resolver. - -Reference: xref::custom-resolvers.adoc#custom-resolver-directive[`@customResolver`] - -== `@cypher` - -The `@cypher` directive overrides field resolution (including `Query` and `Mutation` fields), instead resolving with the specified Cypher. - -Reference: xref::/type-definitions/directives/cypher.adoc[`@cypher` directive] - -== `@default` - -The `@default` directive allows for the setting of a default value for a field on object creation. - -Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-default[`@default`] - -== `@exclude` label:deprecated[] - -This directive is deprecated. - -Use the xref:schema-configuration/type-configuration.adoc#_query[`@query`], xref:schema-configuration/type-configuration.adoc#_mutation[`@mutation`] and the xref:schema-configuration/type-configuration.adoc#_subscription[`@subscription`] directives instead. - -The `@exclude` directive is used on object types to instruct them to be skipped during Query, Mutation and Subscription generation. - -Reference: xref::schema-configuration/type-configuration.adoc#_exclude_deprecated[`@exclude`] - -== `@filterable` - -The `@filterable` directive defines the filters generated for a field. - -Reference: xref:schema-configuration/field-configuration.adoc#_filterable[`@filterable`] - -== `@fulltext` - -The `@fulltext` directive indicates that there should be a Fulltext index inserted into the database for the specified Node and its properties. - -Reference: xref::/type-definitions/directives/indexes-and-constraints.adoc#type-definitions-indexes-fulltext[Fulltext indexes] - -== `@id` - -The `@id` directive marks a field as the unique ID for an object type, and allows for autogeneration of IDs. - -Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-id[`@id`] - -== `@limit` - -The `@limit` is to be used on nodes, and when applied will inject values into Cypher `LIMIT` clauses. - -Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-limit[`@limit`] - -== `@mutation` - -This directive is used to limit the availability of Mutation operations in the library. - -Reference: xref:schema-configuration/type-configuration.adoc#_mutation[`@mutation`] - -== `@node` - -The `@node` directive is used to specify the configuration of a GraphQL object type which represents a Neo4j node. - -Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-node[`@node`] - -[[plural-directive]] -== `@plural` - -The `@plural` directive redefines how to compose the plural of the type for the generated operations. -This is particularly useful for types that are not correctly pluralized or are non-English words. - -Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-plural[`@plural`] - -[[populated-by-directive]] -== `@populatedBy` - -The `@populatedBy` directive is used to specify a callback function that gets executed during GraphQL query parsing, -to populate fields which have not been provided within the input. - -Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-populated-by[`@populatedBy`] - -== `@private` - -The `@private` directive protects fields which should only be available through the xref::ogm/index.adoc[OGM]. - -Reference: xref::ogm/private.adoc[`@private` Directive] - -== `@query` - -This directive is used to limit the availability of Query operations in the library. - -Reference: xref:schema-configuration/type-configuration.adoc#_query[`@query`] - -== `@relationship` - -The `@relationship` directive is used to configure relationships between object types. - -Reference: xref::/type-definitions/types/relationships.adoc[Relationships], xref::schema-configuration/field-configuration.adoc#_relationship[`@relationship`] - -== `@relationshipProperties` - -Required to help you distinguish between interfaces which are used for relationship properties, and otherwise. - -Can only be used on interfaces, as per its definition: - -[source, graphql, indent=0] ----- -"""Required to differentiate between interfaces for relationship properties, and otherwise.""" -directive @relationshipProperties on INTERFACE ----- - -== `@relayId` - -The `@relayId` directive can be used on object type fields, to flag which field should be used as the global node identifier for Relay. Can be used once per type. The use of the `@relayId` directive ensures a unique node property constraint for the field. - -== `@selectable` - -The `@selectable` directive sets the availability of fields on queries and aggregations. - -Reference: xref:schema-configuration/field-configuration.adoc#_selectable[`@selectable`] - -== `@settable` - -The `@settable` directive sets the availability of fields on the create and update inputs. - -Reference: xref:schema-configuration/field-configuration.adoc#_settable[`@settable`] - -== `@subscription` - -This directive is used to limit Subscription events available in the library. - -Reference: xref:schema-configuration/type-configuration.adoc#_subscription[`@subscription`] - -== `@timestamp` - -The `@timestamp` directive flags fields to be used to store timestamps on create/update events. - -Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-timestamp[`@timestamp`] - -== `@unique` - -The `@unique` directive indicates that there should be a uniqueness constraint in the database for the fields that it is applied to. - -Reference: xref::/type-definitions/directives/indexes-and-constraints.adoc#type-definitions-constraints-unique[Unique node property constraints] diff --git a/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc b/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc deleted file mode 100644 index 0d0a5e46..00000000 --- a/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc +++ /dev/null @@ -1,156 +0,0 @@ -[[schema-configuration-type-configuration]] -= Type Configuration - - -When representing a Neo4j Node, a GraphQL Object type produces multiple operation fields in the `Query`, `Mutation`, and `Subscription` types. -For example: - -[source, graphql, indent=0] ----- -type Movie { - title: String - length: Int -} ----- - -From these type definitions, the library generates the following operation fields: - -**Query**: - - * `movies` - * `moviesAggregate` - * `moviesConnection` - -**Mutation**: - - * `createMovies` - * `deleteMovies` - * `updateMovies` - -**Subscription**: - - * `movieCreated` - * `movieUpdated` - * `movieDeleted` -. - -This section explains how to reduce the operation fields produced using the directives `@query`, `@mutation`, and `@subscription`. - -== `@query` - -This directive is used to limit the availability of query operations in the library. - -=== Definition - -[source, graphql, indent=0] ----- -directive @query(read: Boolean! = true, aggregate: Boolean! = false) on OBJECT | SCHEMA ----- - -[NOTE] -==== -Aggregations will no longer be generated by default in the 4.0.0 version of the library. -See xref:migration/v4-migration/index.adoc#opt-in-aggregation[`Opt-in Aggregation`] for more information. -==== - -=== Usage - -==== Disable _movies_ and _moviesConnection_ operations - -[source, graphql, indent=0] ----- -type Movie @query(read: false, aggregate: true) { - title: String - length: Int -} ----- - -==== Disable _moviesAggregate_ operations - -[source, graphql, indent=0] ----- -type Movie @query(read: true, aggregate: false) { - title: String - length: Int -} ----- - -== `@mutation` - -This directive is used to limit the availability of Mutation operations in the library. - -=== Definition - -[source, graphql, indent=0] ----- -enum MutationFields { - CREATE - UPDATE - DELETE -} - -directive @mutation(operations: [MutationFields!]! = [CREATE, UPDATE, DELETE]) on OBJECT | SCHEMA ----- - -=== Usage - -==== Disable Create, Delete, and Update operations for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @mutation(operations: []) { - title: String - length: Int -} ----- - -==== Enable only Create operations for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @mutation(operations: [CREATE]) { - title: String - length: Int -} ----- - -== `@subscription` - -This directive is used to limit Subscription operations in the library. - -=== Definition - -[source, graphql, indent=0] ----- -enum SubscriptionEvent { - CREATED - UPDATED - DELETED - RELATIONSHIP_CREATED - RELATIONSHIP_DELETED -} - -directive @subscription(events: [SubscriptionEvent!]! = [CREATED, UPDATED, DELETED, RELATIONSHIP_CREATED, RELATIONSHIP_DELETED]) on OBJECT | SCHEMA ----- - -=== Usage - -==== Disable subscriptions for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @subscription(events: []) { - title: String - length: Int -} ----- - -==== Enable only _movieCreated_ subscription for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @subscription(events: [CREATED]) { - title: String - length: Int -} ----- diff --git a/modules/ROOT/pages/reference/type-definitions/interfaces.adoc b/modules/ROOT/pages/reference/type-definitions/interfaces.adoc deleted file mode 100644 index adc72a27..00000000 --- a/modules/ROOT/pages/reference/type-definitions/interfaces.adoc +++ /dev/null @@ -1,135 +0,0 @@ -[[schema-configuration-type-configuration]] -= Type Configuration - - -When representing a Neo4j Node, a GraphQL Object type produces multiple operation fields in the `Query`, `Mutation`, and `Subscription` types. -For example: - -[source, graphql, indent=0] ----- -type Movie { - title: String - length: Int -} ----- - -From these type definitions, the library generates the following operation fields: - -**Query**: - - * `movies` - * `moviesAggregate` - * `moviesConnection` - -**Mutation**: - - * `createMovies` - * `deleteMovies` - * `updateMovies` - -**Subscription**: - - * `movieCreated` - * `movieUpdated` - * `movieDeleted` -. - -This section explains how to reduce the operation fields produced using the directives `@query`, `@mutation`, and `@subscription`. - -== `@query` - -This directive is used to limit the availability of query operations in the library. - -=== Definition - -[source, graphql, indent=0] ----- -directive @query(read: Boolean! = true, aggregate: Boolean! = false) on OBJECT | SCHEMA ----- - -[NOTE] -==== -Aggregations will no longer be generated by default in the 4.0.0 version of the library. -See xref:migration/v4-migration/index.adoc#opt-in-aggregation[`Opt-in Aggregation`] for more information. -==== - -[[type-definitions-interfaced-types-querying]] -== Querying an interface - -Which implementations are returned by a query are dictated by the `where` filter applied. - -For example, the following will return all productions with title starting "The " for every actor: - -[source, graphql, indent=0] ----- -enum MutationFields { - CREATE - UPDATE - DELETE -} - -directive @mutation(operations: [MutationFields!]! = [CREATE, UPDATE, DELETE]) on OBJECT | SCHEMA ----- - -=== Usage - -==== Disable Create, Delete, and Update operations for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @mutation(operations: []) { - title: String - length: Int -} ----- - -==== Enable only Create operations for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @mutation(operations: [CREATE]) { - title: String - length: Int -} ----- - -== `@subscription` - -This directive is used to limit Subscription operations in the library. - -=== Definition - -[source, graphql, indent=0] ----- -enum SubscriptionFields { - CREATE - UPDATE - DELETE - CREATE_RELATIONSHIP - DELETE_RELATIONSHIP -} - -directive @subscription(operations: [SubscriptionFields!]! = [CREATE, UPDATE, DELETE, CREATE_RELATIONSHIP, DELETE_RELATIONSHIP]) on OBJECT | SCHEMA ----- - -=== Usage - -==== Disable subscriptions for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @subscription(operations: []) { - title: String - length: Int -} ----- - -==== Enable only _movieCreated_ subscription for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @subscription(operations: [CREATE]) { - title: String - length: Int -} ----- \ No newline at end of file diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index d0a856de..d13ed589 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -10,8 +10,33 @@ This page covers a variety of subscription options offered by the Neo4j GraphQL [NOTE] ==== Only changes made through `@neo4j/graphql` should trigger the events here described. -Changes made directly to the database or using the xref::reference/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. -==== +Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. +=== + +== `CREATE` + +Subscriptions to `CREATE` events listen *only* to newly created nodes, not new relationships. +In this occasion, a new event is triggered for each new node, containing its properties. + +This action is performed with the top-level subscription `[type]Created`, which contains the following fields: + +* `event`: the event triggering this subscription (in this case, `CREATE`). +* `created`: top-level properties of the newly created node, without relationships. +* `timestamp`: the timestamp in which the mutation was made. +If a same query triggers multiple events, they should have the same timestamp. + +As an example, consider the following type definitions: + +[source,graphql,indent=0] +---- +type Movie { + title: String + genre: String +} +---- + +Note, however, that only changes made through `@neo4j/graphql` should trigger events. +Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. == `CREATE` diff --git a/modules/ROOT/partials/reusing-content.adoc b/modules/ROOT/partials/reusing-content.adoc index 464c8ddc..52df337f 100644 --- a/modules/ROOT/partials/reusing-content.adoc +++ b/modules/ROOT/partials/reusing-content.adoc @@ -1 +1,2 @@ +[[include-typescript]] This paragraph can be used anywhere with the syntax shown in xref:content-types.adoc#_partials[]. \ No newline at end of file From 1d001cb10240aec3e0eff040ecf154c1cf2687f2 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Wed, 6 Sep 2023 16:08:12 +0200 Subject: [PATCH 08/13] fixing note formatting --- modules/ROOT/pages/subscriptions/events.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index d13ed589..fffe3756 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -11,7 +11,7 @@ This page covers a variety of subscription options offered by the Neo4j GraphQL ==== Only changes made through `@neo4j/graphql` should trigger the events here described. Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. -=== +==== == `CREATE` From 6ba5335e9c9dcc83b46627028b4854e2a983a83b Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Tue, 5 Sep 2023 15:34:54 +0200 Subject: [PATCH 09/13] Editorial review of the most recent changes --- .../ROOT/pages/authentication-and-authorization/index.adoc | 1 + modules/ROOT/pages/subscriptions/events.adoc | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/ROOT/pages/authentication-and-authorization/index.adoc b/modules/ROOT/pages/authentication-and-authorization/index.adoc index de1e16d7..10adfff4 100644 --- a/modules/ROOT/pages/authentication-and-authorization/index.adoc +++ b/modules/ROOT/pages/authentication-and-authorization/index.adoc @@ -1,3 +1,4 @@ +:description: This section covers authentication andd authorization features in the Neo4j GraphQL Library. = Authentication and Authorization :description: This section covers authentication andd authorization features in the Neo4j GraphQL Library. :page-aliases: auth/index.adoc, auth/setup.adoc, auth/authentication.adoc, \ diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index fffe3756..644da9fb 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -8,10 +8,10 @@ subscriptions/events/update.adoc This page covers a variety of subscription options offered by the Neo4j GraphQL Library. [NOTE] -==== +=== Only changes made through `@neo4j/graphql` should trigger the events here described. Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. -==== +=== == `CREATE` From e76e35c0afb6e88db38158e1769f2e6556f0a173 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Wed, 6 Sep 2023 16:08:12 +0200 Subject: [PATCH 10/13] fixing note formatting --- modules/ROOT/pages/subscriptions/events.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index 644da9fb..93b77837 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -11,7 +11,7 @@ This page covers a variety of subscription options offered by the Neo4j GraphQL === Only changes made through `@neo4j/graphql` should trigger the events here described. Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. -=== +==== == `CREATE` From f1622e1c812a2c754bdb036f20e3d0deedbe433b Mon Sep 17 00:00:00 2001 From: Lidia Zuin <102308961+lidiazuin@users.noreply.github.com> Date: Fri, 15 Sep 2023 11:12:11 +0200 Subject: [PATCH 11/13] Add page-aliases for version 4 (#31) (#32) Co-authored-by: Neil Dewhurst --- .../index.adoc | 1 - .../pages/reference/directives/cypher.adoc | 229 ++++++++++++++++++ .../pages/reference/directives/index.adoc | 161 ++++++++++++ .../type-configuration.adoc | 156 ++++++++++++ .../type-definitions/interfaces.adoc | 135 +++++++++++ modules/ROOT/pages/subscriptions/events.adoc | 26 +- 6 files changed, 682 insertions(+), 26 deletions(-) create mode 100644 modules/ROOT/pages/reference/directives/cypher.adoc create mode 100644 modules/ROOT/pages/reference/directives/index.adoc create mode 100644 modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc create mode 100644 modules/ROOT/pages/reference/type-definitions/interfaces.adoc diff --git a/modules/ROOT/pages/authentication-and-authorization/index.adoc b/modules/ROOT/pages/authentication-and-authorization/index.adoc index 10adfff4..de1e16d7 100644 --- a/modules/ROOT/pages/authentication-and-authorization/index.adoc +++ b/modules/ROOT/pages/authentication-and-authorization/index.adoc @@ -1,4 +1,3 @@ -:description: This section covers authentication andd authorization features in the Neo4j GraphQL Library. = Authentication and Authorization :description: This section covers authentication andd authorization features in the Neo4j GraphQL Library. :page-aliases: auth/index.adoc, auth/setup.adoc, auth/authentication.adoc, \ diff --git a/modules/ROOT/pages/reference/directives/cypher.adoc b/modules/ROOT/pages/reference/directives/cypher.adoc new file mode 100644 index 00000000..390d1351 --- /dev/null +++ b/modules/ROOT/pages/reference/directives/cypher.adoc @@ -0,0 +1,229 @@ +[[type-definitions-cypher]] += `@cypher` directive +:page-aliases: type-definitions/cypher.adoc + +The `@cypher` directive binds a GraphQL field to the result(s) of a Cypher query. + +This directive can be used both for properties in a type or as top level queries: + +== Definition + +[source, graphql, indent=0] +---- +"""Instructs @neo4j/graphql to run the specified Cypher statement in order to resolve the value of the field to which the directive is applied.""" +directive @cypher( + """The Cypher statement to run which returns a value of the same type composition as the field definition on which the directive is applied.""" + statement: String!, + """Name of the returned variable from the Cypher statement.""" + columnName: String! +) on FIELD_DEFINITION +---- + + +== Globals + +Global variables are available for use within the Cypher statement. + +=== `this` + +The value `this` is a reference to the currently resolved node, and it can be used to traverse the graph. + +This can be seen in the usage example xref::/type-definitions/directives/cypher.adoc#type-definitions-cypher-object-usage[On an object type field] below. + +=== `auth` + +The value `auth` is represented by the following TypeScript interface definition: + +[source, typescript, indent=0] +---- +interface Auth { + isAuthenticated: boolean; + roles?: string[]; + jwt: any; +} +---- + +For example, you could use the JWT in the request to return the value of the currently logged in User: + +[source, graphql, indent=0] +---- +type User { + id: String +} + +type Query { + me: User @cypher( + statement: """ + MATCH (user:User {id: $jwt.sub}) + RETURN user + """, + columnName: "user" + ) +} +---- + + +=== `cypherParams` +Use to inject values into the cypher query from the GraphQL context function. + +Inject into context: + +[source, typescript, indent=0] +---- +const server = new ApolloServer({ + typeDefs, +}); + +await startStandaloneServer(server, { + context: async ({ req }) => ({ cypherParams: { userId: "user-id-01" } }), +}); +---- + +Use in cypher query: + +[source, graphql, indent=0] +---- +type Query { + userPosts: [Post] @cypher(statement: """ + MATCH (:User {id: $userId})-[:POSTED]->(p:Post) + RETURN p + """, columnName: "p") +} +---- + +== Return values + +The return value of the Cypher statement must be of the same type to which the directive is applied. + +The variable should also be aliased with a name that must be the same as the named passed to `columnName`, this can be the name of a node or relationship query or an alias in the `RETURN` statement of the cypher. + +=== Scalar values + +The Cypher statement must return a value which matches the scalar type to which the directive was applied. + +[source, graphql, indent=0] +---- +type Query { + randomNumber: Int @cypher(statement: "RETURN rand() as result", columnName: "result") +} +---- + +=== Object types + +When returning an object type, all fields of the type must be available in the Cypher return value. This can be achieved by either returning the entire object from the Cypher query, or returning a map of the fields which are required for the object type. Both approaches are demonstrated below: + +[source, graphql, indent=0] +---- +type User { + id +} + +type Query { + users: [User] + @cypher( + statement: """ + MATCH (u:User) + RETURN u + """, + columnName: "u" + ) +} +---- + +[source, graphql, indent=0] +---- +type User { + id +} + +type Query { + users: [User] @cypher(statement: """ + MATCH (u:User) + RETURN { + id: u.id + } as result + """, columnName: "result") +} +---- + +The downside of the latter approach is that you will need to adjust the return object as you change your object type definition. + +== Usage examples + +[[type-definitions-cypher-object-usage]] +=== On an object type field + +In the example below, a field `similarMovies` is bound to the `Movie` type, to find other movies with an overlap of actors: + +[source, graphql, indent=0] +---- +type Actor { + actorId: ID! + name: String + movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) +} + +type Movie { + movieId: ID! + title: String + description: String + year: Int + actors(limit: Int = 10): [Actor!]! + @relationship(type: "ACTED_IN", direction: IN) + similarMovies(limit: Int = 10): [Movie] + @cypher( + statement: """ + MATCH (this)<-[:ACTED_IN]-(:Actor)-[:ACTED_IN]->(rec:Movie) + WITH rec, COUNT(*) AS score ORDER BY score DESC + RETURN rec LIMIT $limit + """, + columnName: "rec" + ) +} +---- + +=== On a query type field + +The example below demonstrates a simple query to return all of the actors in the database: + +[source, graphql, indent=0] +---- +type Actor { + actorId: ID! + name: String +} + +type Query { + allActors: [Actor] + @cypher( + statement: """ + MATCH (a:Actor) + RETURN a + """, + columnName: "a" + ) +} +---- + +=== On a mutation type field + +The example below demonstrates a simple mutation using a Cypher query to insert a single actor with the specified name argument: + +[source, graphql, indent=0] +---- +type Actor { + actorId: ID! + name: String +} + +type Mutation { + createActor(name: String!): Actor + @cypher( + statement: """ + CREATE (a:Actor {name: $name}) + RETURN a + """, + columnName: "a" + ) +} +---- \ No newline at end of file diff --git a/modules/ROOT/pages/reference/directives/index.adoc b/modules/ROOT/pages/reference/directives/index.adoc new file mode 100644 index 00000000..89535425 --- /dev/null +++ b/modules/ROOT/pages/reference/directives/index.adoc @@ -0,0 +1,161 @@ +[[directives]] += Directives +:page-aliases: directives.adoc + +== `@alias` + +The `@alias` directive will map a GraphQL schema field to a Neo4j property on a node or relationship. + +Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-alias[`@alias`] + +== `@coalesce` + +The `@coalesce` directive exposes a mechanism for querying against non-existent, `null` values on a node. + +Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-coalesce[`@coalesce`] + +[[custom-resolver-directive]] +== `@customResolver` + +The `@customResolver` directive specifies that a field will be resolved by a custom resolver, and allows the specification +of any required fields that will be passed as arguments to the custom resolver. + +Reference: xref::custom-resolvers.adoc#custom-resolver-directive[`@customResolver`] + +== `@cypher` + +The `@cypher` directive overrides field resolution (including `Query` and `Mutation` fields), instead resolving with the specified Cypher. + +Reference: xref::/type-definitions/directives/cypher.adoc[`@cypher` directive] + +== `@default` + +The `@default` directive allows for the setting of a default value for a field on object creation. + +Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-default[`@default`] + +== `@exclude` label:deprecated[] + +This directive is deprecated. + +Use the xref:schema-configuration/type-configuration.adoc#_query[`@query`], xref:schema-configuration/type-configuration.adoc#_mutation[`@mutation`] and the xref:schema-configuration/type-configuration.adoc#_subscription[`@subscription`] directives instead. + +The `@exclude` directive is used on object types to instruct them to be skipped during Query, Mutation and Subscription generation. + +Reference: xref::schema-configuration/type-configuration.adoc#_exclude_deprecated[`@exclude`] + +== `@filterable` + +The `@filterable` directive defines the filters generated for a field. + +Reference: xref:schema-configuration/field-configuration.adoc#_filterable[`@filterable`] + +== `@fulltext` + +The `@fulltext` directive indicates that there should be a Fulltext index inserted into the database for the specified Node and its properties. + +Reference: xref::/type-definitions/directives/indexes-and-constraints.adoc#type-definitions-indexes-fulltext[Fulltext indexes] + +== `@id` + +The `@id` directive marks a field as the unique ID for an object type, and allows for autogeneration of IDs. + +Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-id[`@id`] + +== `@limit` + +The `@limit` is to be used on nodes, and when applied will inject values into Cypher `LIMIT` clauses. + +Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-limit[`@limit`] + +== `@mutation` + +This directive is used to limit the availability of Mutation operations in the library. + +Reference: xref:schema-configuration/type-configuration.adoc#_mutation[`@mutation`] + +== `@node` + +The `@node` directive is used to specify the configuration of a GraphQL object type which represents a Neo4j node. + +Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-node[`@node`] + +[[plural-directive]] +== `@plural` + +The `@plural` directive redefines how to compose the plural of the type for the generated operations. +This is particularly useful for types that are not correctly pluralized or are non-English words. + +Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-plural[`@plural`] + +[[populated-by-directive]] +== `@populatedBy` + +The `@populatedBy` directive is used to specify a callback function that gets executed during GraphQL query parsing, +to populate fields which have not been provided within the input. + +Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-populated-by[`@populatedBy`] + +== `@private` + +The `@private` directive protects fields which should only be available through the xref::ogm/index.adoc[OGM]. + +Reference: xref::ogm/private.adoc[`@private` Directive] + +== `@query` + +This directive is used to limit the availability of Query operations in the library. + +Reference: xref:schema-configuration/type-configuration.adoc#_query[`@query`] + +== `@relationship` + +The `@relationship` directive is used to configure relationships between object types. + +Reference: xref::/type-definitions/types/relationships.adoc[Relationships], xref::schema-configuration/field-configuration.adoc#_relationship[`@relationship`] + +== `@relationshipProperties` + +Required to help you distinguish between interfaces which are used for relationship properties, and otherwise. + +Can only be used on interfaces, as per its definition: + +[source, graphql, indent=0] +---- +"""Required to differentiate between interfaces for relationship properties, and otherwise.""" +directive @relationshipProperties on INTERFACE +---- + +== `@relayId` + +The `@relayId` directive can be used on object type fields, to flag which field should be used as the global node identifier for Relay. Can be used once per type. The use of the `@relayId` directive ensures a unique node property constraint for the field. + +== `@selectable` + +The `@selectable` directive sets the availability of fields on queries and aggregations. + +Reference: xref:schema-configuration/field-configuration.adoc#_selectable[`@selectable`] + +== `@settable` + +The `@settable` directive sets the availability of fields on the create and update inputs. + +Reference: xref:schema-configuration/field-configuration.adoc#_settable[`@settable`] + +== `@subscription` + +This directive is used to limit Subscription events available in the library. + +Reference: xref:schema-configuration/type-configuration.adoc#_subscription[`@subscription`] + +== `@timestamp` + +The `@timestamp` directive flags fields to be used to store timestamps on create/update events. + +Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-timestamp[`@timestamp`] + +== `@unique` + +The `@unique` directive indicates that there should be a uniqueness constraint in the database for the fields that it is applied to. + +Reference: xref::/type-definitions/directives/indexes-and-constraints.adoc#type-definitions-constraints-unique[Unique node property constraints] diff --git a/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc b/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc new file mode 100644 index 00000000..0d0a5e46 --- /dev/null +++ b/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc @@ -0,0 +1,156 @@ +[[schema-configuration-type-configuration]] += Type Configuration + + +When representing a Neo4j Node, a GraphQL Object type produces multiple operation fields in the `Query`, `Mutation`, and `Subscription` types. +For example: + +[source, graphql, indent=0] +---- +type Movie { + title: String + length: Int +} +---- + +From these type definitions, the library generates the following operation fields: + +**Query**: + + * `movies` + * `moviesAggregate` + * `moviesConnection` + +**Mutation**: + + * `createMovies` + * `deleteMovies` + * `updateMovies` + +**Subscription**: + + * `movieCreated` + * `movieUpdated` + * `movieDeleted` +. + +This section explains how to reduce the operation fields produced using the directives `@query`, `@mutation`, and `@subscription`. + +== `@query` + +This directive is used to limit the availability of query operations in the library. + +=== Definition + +[source, graphql, indent=0] +---- +directive @query(read: Boolean! = true, aggregate: Boolean! = false) on OBJECT | SCHEMA +---- + +[NOTE] +==== +Aggregations will no longer be generated by default in the 4.0.0 version of the library. +See xref:migration/v4-migration/index.adoc#opt-in-aggregation[`Opt-in Aggregation`] for more information. +==== + +=== Usage + +==== Disable _movies_ and _moviesConnection_ operations + +[source, graphql, indent=0] +---- +type Movie @query(read: false, aggregate: true) { + title: String + length: Int +} +---- + +==== Disable _moviesAggregate_ operations + +[source, graphql, indent=0] +---- +type Movie @query(read: true, aggregate: false) { + title: String + length: Int +} +---- + +== `@mutation` + +This directive is used to limit the availability of Mutation operations in the library. + +=== Definition + +[source, graphql, indent=0] +---- +enum MutationFields { + CREATE + UPDATE + DELETE +} + +directive @mutation(operations: [MutationFields!]! = [CREATE, UPDATE, DELETE]) on OBJECT | SCHEMA +---- + +=== Usage + +==== Disable Create, Delete, and Update operations for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @mutation(operations: []) { + title: String + length: Int +} +---- + +==== Enable only Create operations for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @mutation(operations: [CREATE]) { + title: String + length: Int +} +---- + +== `@subscription` + +This directive is used to limit Subscription operations in the library. + +=== Definition + +[source, graphql, indent=0] +---- +enum SubscriptionEvent { + CREATED + UPDATED + DELETED + RELATIONSHIP_CREATED + RELATIONSHIP_DELETED +} + +directive @subscription(events: [SubscriptionEvent!]! = [CREATED, UPDATED, DELETED, RELATIONSHIP_CREATED, RELATIONSHIP_DELETED]) on OBJECT | SCHEMA +---- + +=== Usage + +==== Disable subscriptions for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @subscription(events: []) { + title: String + length: Int +} +---- + +==== Enable only _movieCreated_ subscription for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @subscription(events: [CREATED]) { + title: String + length: Int +} +---- diff --git a/modules/ROOT/pages/reference/type-definitions/interfaces.adoc b/modules/ROOT/pages/reference/type-definitions/interfaces.adoc new file mode 100644 index 00000000..adc72a27 --- /dev/null +++ b/modules/ROOT/pages/reference/type-definitions/interfaces.adoc @@ -0,0 +1,135 @@ +[[schema-configuration-type-configuration]] += Type Configuration + + +When representing a Neo4j Node, a GraphQL Object type produces multiple operation fields in the `Query`, `Mutation`, and `Subscription` types. +For example: + +[source, graphql, indent=0] +---- +type Movie { + title: String + length: Int +} +---- + +From these type definitions, the library generates the following operation fields: + +**Query**: + + * `movies` + * `moviesAggregate` + * `moviesConnection` + +**Mutation**: + + * `createMovies` + * `deleteMovies` + * `updateMovies` + +**Subscription**: + + * `movieCreated` + * `movieUpdated` + * `movieDeleted` +. + +This section explains how to reduce the operation fields produced using the directives `@query`, `@mutation`, and `@subscription`. + +== `@query` + +This directive is used to limit the availability of query operations in the library. + +=== Definition + +[source, graphql, indent=0] +---- +directive @query(read: Boolean! = true, aggregate: Boolean! = false) on OBJECT | SCHEMA +---- + +[NOTE] +==== +Aggregations will no longer be generated by default in the 4.0.0 version of the library. +See xref:migration/v4-migration/index.adoc#opt-in-aggregation[`Opt-in Aggregation`] for more information. +==== + +[[type-definitions-interfaced-types-querying]] +== Querying an interface + +Which implementations are returned by a query are dictated by the `where` filter applied. + +For example, the following will return all productions with title starting "The " for every actor: + +[source, graphql, indent=0] +---- +enum MutationFields { + CREATE + UPDATE + DELETE +} + +directive @mutation(operations: [MutationFields!]! = [CREATE, UPDATE, DELETE]) on OBJECT | SCHEMA +---- + +=== Usage + +==== Disable Create, Delete, and Update operations for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @mutation(operations: []) { + title: String + length: Int +} +---- + +==== Enable only Create operations for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @mutation(operations: [CREATE]) { + title: String + length: Int +} +---- + +== `@subscription` + +This directive is used to limit Subscription operations in the library. + +=== Definition + +[source, graphql, indent=0] +---- +enum SubscriptionFields { + CREATE + UPDATE + DELETE + CREATE_RELATIONSHIP + DELETE_RELATIONSHIP +} + +directive @subscription(operations: [SubscriptionFields!]! = [CREATE, UPDATE, DELETE, CREATE_RELATIONSHIP, DELETE_RELATIONSHIP]) on OBJECT | SCHEMA +---- + +=== Usage + +==== Disable subscriptions for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @subscription(operations: []) { + title: String + length: Int +} +---- + +==== Enable only _movieCreated_ subscription for _Movie_ + +[source, graphql, indent=0] +---- +type Movie @subscription(operations: [CREATE]) { + title: String + length: Int +} +---- \ No newline at end of file diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index 93b77837..18dea0ac 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -10,33 +10,9 @@ This page covers a variety of subscription options offered by the Neo4j GraphQL [NOTE] === Only changes made through `@neo4j/graphql` should trigger the events here described. -Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. +Changes made directly to the database or using the xref::reference/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. ==== -== `CREATE` - -Subscriptions to `CREATE` events listen *only* to newly created nodes, not new relationships. -In this occasion, a new event is triggered for each new node, containing its properties. - -This action is performed with the top-level subscription `[type]Created`, which contains the following fields: - -* `event`: the event triggering this subscription (in this case, `CREATE`). -* `created`: top-level properties of the newly created node, without relationships. -* `timestamp`: the timestamp in which the mutation was made. -If a same query triggers multiple events, they should have the same timestamp. - -As an example, consider the following type definitions: - -[source,graphql,indent=0] ----- -type Movie { - title: String - genre: String -} ----- - -Note, however, that only changes made through `@neo4j/graphql` should trigger events. -Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. == `CREATE` From 5acdc6da6da2cfdcc1c1269c35db01bac9505ae3 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Tue, 5 Sep 2023 15:34:54 +0200 Subject: [PATCH 12/13] Editorial review of the most recent changes --- .../pages/reference/directives/cypher.adoc | 229 ------------------ .../pages/reference/directives/index.adoc | 161 ------------ .../type-configuration.adoc | 156 ------------ .../type-definitions/interfaces.adoc | 135 ----------- modules/ROOT/pages/subscriptions/events.adoc | 28 ++- 5 files changed, 26 insertions(+), 683 deletions(-) delete mode 100644 modules/ROOT/pages/reference/directives/cypher.adoc delete mode 100644 modules/ROOT/pages/reference/directives/index.adoc delete mode 100644 modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc delete mode 100644 modules/ROOT/pages/reference/type-definitions/interfaces.adoc diff --git a/modules/ROOT/pages/reference/directives/cypher.adoc b/modules/ROOT/pages/reference/directives/cypher.adoc deleted file mode 100644 index 390d1351..00000000 --- a/modules/ROOT/pages/reference/directives/cypher.adoc +++ /dev/null @@ -1,229 +0,0 @@ -[[type-definitions-cypher]] -= `@cypher` directive -:page-aliases: type-definitions/cypher.adoc - -The `@cypher` directive binds a GraphQL field to the result(s) of a Cypher query. - -This directive can be used both for properties in a type or as top level queries: - -== Definition - -[source, graphql, indent=0] ----- -"""Instructs @neo4j/graphql to run the specified Cypher statement in order to resolve the value of the field to which the directive is applied.""" -directive @cypher( - """The Cypher statement to run which returns a value of the same type composition as the field definition on which the directive is applied.""" - statement: String!, - """Name of the returned variable from the Cypher statement.""" - columnName: String! -) on FIELD_DEFINITION ----- - - -== Globals - -Global variables are available for use within the Cypher statement. - -=== `this` - -The value `this` is a reference to the currently resolved node, and it can be used to traverse the graph. - -This can be seen in the usage example xref::/type-definitions/directives/cypher.adoc#type-definitions-cypher-object-usage[On an object type field] below. - -=== `auth` - -The value `auth` is represented by the following TypeScript interface definition: - -[source, typescript, indent=0] ----- -interface Auth { - isAuthenticated: boolean; - roles?: string[]; - jwt: any; -} ----- - -For example, you could use the JWT in the request to return the value of the currently logged in User: - -[source, graphql, indent=0] ----- -type User { - id: String -} - -type Query { - me: User @cypher( - statement: """ - MATCH (user:User {id: $jwt.sub}) - RETURN user - """, - columnName: "user" - ) -} ----- - - -=== `cypherParams` -Use to inject values into the cypher query from the GraphQL context function. - -Inject into context: - -[source, typescript, indent=0] ----- -const server = new ApolloServer({ - typeDefs, -}); - -await startStandaloneServer(server, { - context: async ({ req }) => ({ cypherParams: { userId: "user-id-01" } }), -}); ----- - -Use in cypher query: - -[source, graphql, indent=0] ----- -type Query { - userPosts: [Post] @cypher(statement: """ - MATCH (:User {id: $userId})-[:POSTED]->(p:Post) - RETURN p - """, columnName: "p") -} ----- - -== Return values - -The return value of the Cypher statement must be of the same type to which the directive is applied. - -The variable should also be aliased with a name that must be the same as the named passed to `columnName`, this can be the name of a node or relationship query or an alias in the `RETURN` statement of the cypher. - -=== Scalar values - -The Cypher statement must return a value which matches the scalar type to which the directive was applied. - -[source, graphql, indent=0] ----- -type Query { - randomNumber: Int @cypher(statement: "RETURN rand() as result", columnName: "result") -} ----- - -=== Object types - -When returning an object type, all fields of the type must be available in the Cypher return value. This can be achieved by either returning the entire object from the Cypher query, or returning a map of the fields which are required for the object type. Both approaches are demonstrated below: - -[source, graphql, indent=0] ----- -type User { - id -} - -type Query { - users: [User] - @cypher( - statement: """ - MATCH (u:User) - RETURN u - """, - columnName: "u" - ) -} ----- - -[source, graphql, indent=0] ----- -type User { - id -} - -type Query { - users: [User] @cypher(statement: """ - MATCH (u:User) - RETURN { - id: u.id - } as result - """, columnName: "result") -} ----- - -The downside of the latter approach is that you will need to adjust the return object as you change your object type definition. - -== Usage examples - -[[type-definitions-cypher-object-usage]] -=== On an object type field - -In the example below, a field `similarMovies` is bound to the `Movie` type, to find other movies with an overlap of actors: - -[source, graphql, indent=0] ----- -type Actor { - actorId: ID! - name: String - movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) -} - -type Movie { - movieId: ID! - title: String - description: String - year: Int - actors(limit: Int = 10): [Actor!]! - @relationship(type: "ACTED_IN", direction: IN) - similarMovies(limit: Int = 10): [Movie] - @cypher( - statement: """ - MATCH (this)<-[:ACTED_IN]-(:Actor)-[:ACTED_IN]->(rec:Movie) - WITH rec, COUNT(*) AS score ORDER BY score DESC - RETURN rec LIMIT $limit - """, - columnName: "rec" - ) -} ----- - -=== On a query type field - -The example below demonstrates a simple query to return all of the actors in the database: - -[source, graphql, indent=0] ----- -type Actor { - actorId: ID! - name: String -} - -type Query { - allActors: [Actor] - @cypher( - statement: """ - MATCH (a:Actor) - RETURN a - """, - columnName: "a" - ) -} ----- - -=== On a mutation type field - -The example below demonstrates a simple mutation using a Cypher query to insert a single actor with the specified name argument: - -[source, graphql, indent=0] ----- -type Actor { - actorId: ID! - name: String -} - -type Mutation { - createActor(name: String!): Actor - @cypher( - statement: """ - CREATE (a:Actor {name: $name}) - RETURN a - """, - columnName: "a" - ) -} ----- \ No newline at end of file diff --git a/modules/ROOT/pages/reference/directives/index.adoc b/modules/ROOT/pages/reference/directives/index.adoc deleted file mode 100644 index 89535425..00000000 --- a/modules/ROOT/pages/reference/directives/index.adoc +++ /dev/null @@ -1,161 +0,0 @@ -[[directives]] -= Directives -:page-aliases: directives.adoc - -== `@alias` - -The `@alias` directive will map a GraphQL schema field to a Neo4j property on a node or relationship. - -Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-alias[`@alias`] - -== `@coalesce` - -The `@coalesce` directive exposes a mechanism for querying against non-existent, `null` values on a node. - -Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-coalesce[`@coalesce`] - -[[custom-resolver-directive]] -== `@customResolver` - -The `@customResolver` directive specifies that a field will be resolved by a custom resolver, and allows the specification -of any required fields that will be passed as arguments to the custom resolver. - -Reference: xref::custom-resolvers.adoc#custom-resolver-directive[`@customResolver`] - -== `@cypher` - -The `@cypher` directive overrides field resolution (including `Query` and `Mutation` fields), instead resolving with the specified Cypher. - -Reference: xref::/type-definitions/directives/cypher.adoc[`@cypher` directive] - -== `@default` - -The `@default` directive allows for the setting of a default value for a field on object creation. - -Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-default[`@default`] - -== `@exclude` label:deprecated[] - -This directive is deprecated. - -Use the xref:schema-configuration/type-configuration.adoc#_query[`@query`], xref:schema-configuration/type-configuration.adoc#_mutation[`@mutation`] and the xref:schema-configuration/type-configuration.adoc#_subscription[`@subscription`] directives instead. - -The `@exclude` directive is used on object types to instruct them to be skipped during Query, Mutation and Subscription generation. - -Reference: xref::schema-configuration/type-configuration.adoc#_exclude_deprecated[`@exclude`] - -== `@filterable` - -The `@filterable` directive defines the filters generated for a field. - -Reference: xref:schema-configuration/field-configuration.adoc#_filterable[`@filterable`] - -== `@fulltext` - -The `@fulltext` directive indicates that there should be a Fulltext index inserted into the database for the specified Node and its properties. - -Reference: xref::/type-definitions/directives/indexes-and-constraints.adoc#type-definitions-indexes-fulltext[Fulltext indexes] - -== `@id` - -The `@id` directive marks a field as the unique ID for an object type, and allows for autogeneration of IDs. - -Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-id[`@id`] - -== `@limit` - -The `@limit` is to be used on nodes, and when applied will inject values into Cypher `LIMIT` clauses. - -Reference: xref::/type-definitions/directives/default-values.adoc#type-definitions-default-values-limit[`@limit`] - -== `@mutation` - -This directive is used to limit the availability of Mutation operations in the library. - -Reference: xref:schema-configuration/type-configuration.adoc#_mutation[`@mutation`] - -== `@node` - -The `@node` directive is used to specify the configuration of a GraphQL object type which represents a Neo4j node. - -Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-node[`@node`] - -[[plural-directive]] -== `@plural` - -The `@plural` directive redefines how to compose the plural of the type for the generated operations. -This is particularly useful for types that are not correctly pluralized or are non-English words. - -Reference: xref::/type-definitions/directives/database-mapping.adoc#type-definitions-plural[`@plural`] - -[[populated-by-directive]] -== `@populatedBy` - -The `@populatedBy` directive is used to specify a callback function that gets executed during GraphQL query parsing, -to populate fields which have not been provided within the input. - -Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-populated-by[`@populatedBy`] - -== `@private` - -The `@private` directive protects fields which should only be available through the xref::ogm/index.adoc[OGM]. - -Reference: xref::ogm/private.adoc[`@private` Directive] - -== `@query` - -This directive is used to limit the availability of Query operations in the library. - -Reference: xref:schema-configuration/type-configuration.adoc#_query[`@query`] - -== `@relationship` - -The `@relationship` directive is used to configure relationships between object types. - -Reference: xref::/type-definitions/types/relationships.adoc[Relationships], xref::schema-configuration/field-configuration.adoc#_relationship[`@relationship`] - -== `@relationshipProperties` - -Required to help you distinguish between interfaces which are used for relationship properties, and otherwise. - -Can only be used on interfaces, as per its definition: - -[source, graphql, indent=0] ----- -"""Required to differentiate between interfaces for relationship properties, and otherwise.""" -directive @relationshipProperties on INTERFACE ----- - -== `@relayId` - -The `@relayId` directive can be used on object type fields, to flag which field should be used as the global node identifier for Relay. Can be used once per type. The use of the `@relayId` directive ensures a unique node property constraint for the field. - -== `@selectable` - -The `@selectable` directive sets the availability of fields on queries and aggregations. - -Reference: xref:schema-configuration/field-configuration.adoc#_selectable[`@selectable`] - -== `@settable` - -The `@settable` directive sets the availability of fields on the create and update inputs. - -Reference: xref:schema-configuration/field-configuration.adoc#_settable[`@settable`] - -== `@subscription` - -This directive is used to limit Subscription events available in the library. - -Reference: xref:schema-configuration/type-configuration.adoc#_subscription[`@subscription`] - -== `@timestamp` - -The `@timestamp` directive flags fields to be used to store timestamps on create/update events. - -Reference: xref::/type-definitions/directives/autogeneration.adoc#type-definitions-autogeneration-timestamp[`@timestamp`] - -== `@unique` - -The `@unique` directive indicates that there should be a uniqueness constraint in the database for the fields that it is applied to. - -Reference: xref::/type-definitions/directives/indexes-and-constraints.adoc#type-definitions-constraints-unique[Unique node property constraints] diff --git a/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc b/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc deleted file mode 100644 index 0d0a5e46..00000000 --- a/modules/ROOT/pages/reference/directives/schema-configuration/type-configuration.adoc +++ /dev/null @@ -1,156 +0,0 @@ -[[schema-configuration-type-configuration]] -= Type Configuration - - -When representing a Neo4j Node, a GraphQL Object type produces multiple operation fields in the `Query`, `Mutation`, and `Subscription` types. -For example: - -[source, graphql, indent=0] ----- -type Movie { - title: String - length: Int -} ----- - -From these type definitions, the library generates the following operation fields: - -**Query**: - - * `movies` - * `moviesAggregate` - * `moviesConnection` - -**Mutation**: - - * `createMovies` - * `deleteMovies` - * `updateMovies` - -**Subscription**: - - * `movieCreated` - * `movieUpdated` - * `movieDeleted` -. - -This section explains how to reduce the operation fields produced using the directives `@query`, `@mutation`, and `@subscription`. - -== `@query` - -This directive is used to limit the availability of query operations in the library. - -=== Definition - -[source, graphql, indent=0] ----- -directive @query(read: Boolean! = true, aggregate: Boolean! = false) on OBJECT | SCHEMA ----- - -[NOTE] -==== -Aggregations will no longer be generated by default in the 4.0.0 version of the library. -See xref:migration/v4-migration/index.adoc#opt-in-aggregation[`Opt-in Aggregation`] for more information. -==== - -=== Usage - -==== Disable _movies_ and _moviesConnection_ operations - -[source, graphql, indent=0] ----- -type Movie @query(read: false, aggregate: true) { - title: String - length: Int -} ----- - -==== Disable _moviesAggregate_ operations - -[source, graphql, indent=0] ----- -type Movie @query(read: true, aggregate: false) { - title: String - length: Int -} ----- - -== `@mutation` - -This directive is used to limit the availability of Mutation operations in the library. - -=== Definition - -[source, graphql, indent=0] ----- -enum MutationFields { - CREATE - UPDATE - DELETE -} - -directive @mutation(operations: [MutationFields!]! = [CREATE, UPDATE, DELETE]) on OBJECT | SCHEMA ----- - -=== Usage - -==== Disable Create, Delete, and Update operations for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @mutation(operations: []) { - title: String - length: Int -} ----- - -==== Enable only Create operations for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @mutation(operations: [CREATE]) { - title: String - length: Int -} ----- - -== `@subscription` - -This directive is used to limit Subscription operations in the library. - -=== Definition - -[source, graphql, indent=0] ----- -enum SubscriptionEvent { - CREATED - UPDATED - DELETED - RELATIONSHIP_CREATED - RELATIONSHIP_DELETED -} - -directive @subscription(events: [SubscriptionEvent!]! = [CREATED, UPDATED, DELETED, RELATIONSHIP_CREATED, RELATIONSHIP_DELETED]) on OBJECT | SCHEMA ----- - -=== Usage - -==== Disable subscriptions for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @subscription(events: []) { - title: String - length: Int -} ----- - -==== Enable only _movieCreated_ subscription for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @subscription(events: [CREATED]) { - title: String - length: Int -} ----- diff --git a/modules/ROOT/pages/reference/type-definitions/interfaces.adoc b/modules/ROOT/pages/reference/type-definitions/interfaces.adoc deleted file mode 100644 index adc72a27..00000000 --- a/modules/ROOT/pages/reference/type-definitions/interfaces.adoc +++ /dev/null @@ -1,135 +0,0 @@ -[[schema-configuration-type-configuration]] -= Type Configuration - - -When representing a Neo4j Node, a GraphQL Object type produces multiple operation fields in the `Query`, `Mutation`, and `Subscription` types. -For example: - -[source, graphql, indent=0] ----- -type Movie { - title: String - length: Int -} ----- - -From these type definitions, the library generates the following operation fields: - -**Query**: - - * `movies` - * `moviesAggregate` - * `moviesConnection` - -**Mutation**: - - * `createMovies` - * `deleteMovies` - * `updateMovies` - -**Subscription**: - - * `movieCreated` - * `movieUpdated` - * `movieDeleted` -. - -This section explains how to reduce the operation fields produced using the directives `@query`, `@mutation`, and `@subscription`. - -== `@query` - -This directive is used to limit the availability of query operations in the library. - -=== Definition - -[source, graphql, indent=0] ----- -directive @query(read: Boolean! = true, aggregate: Boolean! = false) on OBJECT | SCHEMA ----- - -[NOTE] -==== -Aggregations will no longer be generated by default in the 4.0.0 version of the library. -See xref:migration/v4-migration/index.adoc#opt-in-aggregation[`Opt-in Aggregation`] for more information. -==== - -[[type-definitions-interfaced-types-querying]] -== Querying an interface - -Which implementations are returned by a query are dictated by the `where` filter applied. - -For example, the following will return all productions with title starting "The " for every actor: - -[source, graphql, indent=0] ----- -enum MutationFields { - CREATE - UPDATE - DELETE -} - -directive @mutation(operations: [MutationFields!]! = [CREATE, UPDATE, DELETE]) on OBJECT | SCHEMA ----- - -=== Usage - -==== Disable Create, Delete, and Update operations for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @mutation(operations: []) { - title: String - length: Int -} ----- - -==== Enable only Create operations for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @mutation(operations: [CREATE]) { - title: String - length: Int -} ----- - -== `@subscription` - -This directive is used to limit Subscription operations in the library. - -=== Definition - -[source, graphql, indent=0] ----- -enum SubscriptionFields { - CREATE - UPDATE - DELETE - CREATE_RELATIONSHIP - DELETE_RELATIONSHIP -} - -directive @subscription(operations: [SubscriptionFields!]! = [CREATE, UPDATE, DELETE, CREATE_RELATIONSHIP, DELETE_RELATIONSHIP]) on OBJECT | SCHEMA ----- - -=== Usage - -==== Disable subscriptions for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @subscription(operations: []) { - title: String - length: Int -} ----- - -==== Enable only _movieCreated_ subscription for _Movie_ - -[source, graphql, indent=0] ----- -type Movie @subscription(operations: [CREATE]) { - title: String - length: Int -} ----- \ No newline at end of file diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index 18dea0ac..644da9fb 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -10,9 +10,33 @@ This page covers a variety of subscription options offered by the Neo4j GraphQL [NOTE] === Only changes made through `@neo4j/graphql` should trigger the events here described. -Changes made directly to the database or using the xref::reference/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. -==== +Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. +=== + +== `CREATE` + +Subscriptions to `CREATE` events listen *only* to newly created nodes, not new relationships. +In this occasion, a new event is triggered for each new node, containing its properties. + +This action is performed with the top-level subscription `[type]Created`, which contains the following fields: + +* `event`: the event triggering this subscription (in this case, `CREATE`). +* `created`: top-level properties of the newly created node, without relationships. +* `timestamp`: the timestamp in which the mutation was made. +If a same query triggers multiple events, they should have the same timestamp. + +As an example, consider the following type definitions: + +[source,graphql,indent=0] +---- +type Movie { + title: String + genre: String +} +---- +Note, however, that only changes made through `@neo4j/graphql` should trigger events. +Changes made directly to the database or using the xref::type-definitions/directives/cypher.adoc[`@cypher` directive] will **not** trigger any event. == `CREATE` From 146d5c860cd15fa544da1d007f566dc6fd030b71 Mon Sep 17 00:00:00 2001 From: Michael Webb <28074382+mjfwebb@users.noreply.github.com> Date: Mon, 13 Nov 2023 14:21:49 +0100 Subject: [PATCH 13/13] Add how to add session and transaction to the execution context (#59) --- modules/ROOT/pages/driver-configuration.adoc | 69 +++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/driver-configuration.adoc b/modules/ROOT/pages/driver-configuration.adoc index 839fcbe0..2b009e98 100644 --- a/modules/ROOT/pages/driver-configuration.adoc +++ b/modules/ROOT/pages/driver-configuration.adoc @@ -76,6 +76,73 @@ await startStandaloneServer(server, { ---- +==== Session in context + +[source, javascript, indent=0] +---- +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Neo4jGraphQL } from "@neo4j/graphql"; +import neo4j from "neo4j-driver"; + +const typeDefs = `#graphql + type User { + name: String + } +`; + +const driver = neo4j.driver( + "bolt://localhost:7687", + neo4j.auth.basic("neo4j", "password") +); +const session = driver.session(); + +const neoSchema = new Neo4jGraphQL({ typeDefs, driver }); + +const server = new ApolloServer({ + schema: await neoSchema.getSchema(), +}); + +await startStandaloneServer(server, { + context: async ({ req }) => ({ req, executionContext: session }), +}); + +---- + +==== Transaction in context + +[source, javascript, indent=0] +---- +import { ApolloServer } from "@apollo/server"; +import { startStandaloneServer } from "@apollo/server/standalone"; +import { Neo4jGraphQL } from "@neo4j/graphql"; +import neo4j from "neo4j-driver"; + +const typeDefs = `#graphql + type User { + name: String + } +`; + +const driver = neo4j.driver( + "bolt://localhost:7687", + neo4j.auth.basic("neo4j", "password") +); +const session = driver.transaction(); +const transaction = session.beginTransaction(); + +const neoSchema = new Neo4jGraphQL({ typeDefs, driver }); + +const server = new ApolloServer({ + schema: await neoSchema.getSchema(), +}); + +await startStandaloneServer(server, { + context: async ({ req }) => ({ req, executionContext: transaction }), +}); + +---- + === OGM [source, javascript, indent=0] @@ -180,4 +247,4 @@ const server = new ApolloServer({ await startStandaloneServer(server, { context: async ({ req }) => ({ req, sessionConfig: { database: "my-database" }}), }); ----- \ No newline at end of file +----