From 61c54ee8951649199ea9cf5f859f76aba22812c0 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 c17b28c48c4862ce4765bc3adec4e582ece7ae64 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 a657174dbfdc915ed9b3dca78c62ac6d78f5011d 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 352e0ef3c5af9680aa05fa5c03bc6dfafc38c86f 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 5e9e592d9e9ed80c26bccaabf2b3ce6a2d247794 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 cf3b5c32bcd479e0489210b33c7f69175d50cadc 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 bd926211ccc14d3c2995ba519fa46160e4c14f60 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 b6c88051b698326245c26be54a4a44192db83438 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 5d837cff00406851efe677245ae75b0fa7eb149e 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 50b1d95e7967f998ec973f5fb2eee4f60ff21bc4 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 ae73ab028507b8a29a2d30fb9f2c298ca14672a3 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 9bce80743f19a9c730f4909f16bf4519d3d719a6 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 21d22c3e87b9235f44e9b9de482628e8ccfc3843 Mon Sep 17 00:00:00 2001 From: Lidia Zuin <102308961+lidiazuin@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:51:59 +0200 Subject: [PATCH 13/13] Adding link to driver configuration in the getting started page (#50) * Adding link to driver configuration in the getting started page * replacing word --- modules/ROOT/pages/getting-started/index.adoc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/ROOT/pages/getting-started/index.adoc b/modules/ROOT/pages/getting-started/index.adoc index 6a385f2d..23f1dbb9 100644 --- a/modules/ROOT/pages/getting-started/index.adoc +++ b/modules/ROOT/pages/getting-started/index.adoc @@ -261,4 +261,5 @@ Since only one "Movie" and one "Actor" were added, this is the result you should This concludes the tutorial. By now, you should have a GraphQL API connected to a Neo4j database, to which you added two nodes. -To learn more, keep reading the documentation about xref:queries-aggregations/index.adoc[Queries and aggregations] or alternatively learn how to use the xref:getting-started/toolbox.adoc[Neo4j GraphQL Toolbox]. \ No newline at end of file +To learn more, keep reading the documentation about xref:queries-aggregations/index.adoc[Queries and aggregations] or alternatively learn how to use the xref:getting-started/toolbox.adoc[Neo4j GraphQL Toolbox]. +For more advanced database settings, refer to the xref:driver-configuration.adoc[Driver configuration] page. \ No newline at end of file