From 7811c3008fae734ebfb9abec1b4a8e549f89cea6 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Tue, 5 Sep 2023 15:34:54 +0200 Subject: [PATCH 01/11] Editorial review of the most recent changes --- .../authorization.adoc | 6 +-- .../index.adoc | 6 +-- .../pages/integrations/apollo-federation.adoc | 40 ++++++++++--------- modules/ROOT/partials/reusing-content.adoc | 1 + 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/modules/ROOT/pages/authentication-and-authorization/authorization.adoc b/modules/ROOT/pages/authentication-and-authorization/authorization.adoc index 4fab80aa..95e1784d 100644 --- a/modules/ROOT/pages/authentication-and-authorization/authorization.adoc +++ b/modules/ROOT/pages/authentication-and-authorization/authorization.adoc @@ -2,8 +2,8 @@ :description: This page describes how to set up authorization features in the Neo4j GraphQL Library. = Authorization -Authorization rules cover what specific data a generated Cypher query is executed against. -They use predicates to evaluate the Cypher generated from a GraphQL query, thus allowing or disallowing execution within the context of nodes and their properties. +Authorization rules cover to what specific data a generated Cypher query is executed against. +They use predicates to evaluate the Cypher generated from a GraphQL query, thus allowing or not execution within the context of nodes and their properties. All authorization rules have an implied requirement for authentication, given that the rules are normally evaluated against values in the JWT payload. @@ -63,7 +63,7 @@ type User @authorization(validate: [ Authentication is implicitly required for every authorization check by default, but this can be disabled on a per-rule basis. This could be the case, for instance, when a node has a property which flags whether the node should be public or not. -For instance, in the case where some `Post` nodes are private and belong to a particular `User`, while other `Post` nodes are public and readable by any user, here is how to set this up: +For instance, in case `Post` nodes might be private and belong to a particular `User`, or be public and readable by any user, here is how to set this up: [source, graphql, indent=0] ---- diff --git a/modules/ROOT/pages/authentication-and-authorization/index.adoc b/modules/ROOT/pages/authentication-and-authorization/index.adoc index f51c7a3e..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, \ @@ -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/integrations/apollo-federation.adoc b/modules/ROOT/pages/integrations/apollo-federation.adoc index 0882c0fc..bd67965e 100644 --- a/modules/ROOT/pages/integrations/apollo-federation.adoc +++ b/modules/ROOT/pages/integrations/apollo-federation.adoc @@ -65,18 +65,19 @@ npm pkg set type="module" ---- + [NOTE] -=== +==== This how-to guide sets up the project using ES Modules, which allows the usage of features such as top-level `await`. -=== +==== . Choose TypeScript or JavaScript to proceed with the setup: -+ + [.tabbed-example] ==== [.include-with-Typescript] ===== -. Create a `src` directory with an empty `index.ts` file to contain the entrypoint to your code: + +. Create a src directory with an empty index.ts file to contain the entrypoint to your code: + [source, bash] ---- @@ -91,14 +92,14 @@ touch src/index.ts npm install --save-dev typescript @types/node @tsconfig/node-lts ---- + -. Create an empty `tsconfig.json` file containing the compiler configuration for TypeScript: +. Create an empty tsconfig.json file containing the compiler configuration for TypeScript: + [source, bash] ---- touch tsconfig.json ---- + -. Add the following configuration to the `tsconfig.json` file: +. Add the following configuration to the tsconfig.json file: + [source, json] ---- @@ -112,12 +113,12 @@ touch tsconfig.json ---- + [NOTE] -=== -This configuration extends the https://github.com/tsconfig/bases#node-lts-tsconfigjson[community base for Node.js LTS], provided by the `@tsconfig/node-lts` package installed above. +====== +This configuration extends the https://github.com/tsconfig/bases#node-lts-tsconfigjson[community base for Node.js LTS], provided by the @tsconfig/node-lts package installed above. For more information on the available options, see the https://www.typescriptlang.org/tsconfig[TypeScript Compiler docs]. -=== +====== + -. Replace the default `scripts` entry in your `package.json` file with the following: +. Replace the default scripts entry in your package.json file with the following: + [source, json] ---- @@ -134,16 +135,17 @@ For more information on the available options, see the https://www.typescriptlan [.include-with-JavaScript] ===== -. Create a `src` directory with an empty `index.js` file to contain the entrypoint to your code: -+ + +Create a `src` directory with an empty `index.js` file to contain the entrypoint to your code: + [source, bash] ---- mkdir src touch src/index.js ---- -+ -. Replace the default `scripts` entry in your `package.json` file with the following: -+ + +Replace the default `scripts` entry in your `package.json` file with the following: + [source, json] ---- { @@ -155,7 +157,9 @@ touch src/index.js } ---- ===== + ==== + + . This guide requires the installation of the following dependencies: + @@ -190,10 +194,10 @@ const typeDefs = `#graphql ---- [NOTE] -=== +==== This example only includes the Federation `@key` directive. To use more https://www.apollographql.com/docs/federation/federated-types/federated-directives[Federation directives], add them to the `import` array. -=== +==== == Define an entity @@ -269,4 +273,4 @@ For further iteration, this subgraph can also be composed into a supergraph. Check Apollo's guides for more instructions: * https://www.apollographql.com/docs/federation/quickstart/studio-composition[Composition in Apollo Studio] -* https://www.apollographql.com/docs/federation/quickstart/local-composition[Local composition] +* https://www.apollographql.com/docs/federation/quickstart/local-composition[Local composition] \ No newline at end of file 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 9aba70e0a4a00f185bdf008b07ee8b50d9e42db1 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Wed, 6 Sep 2023 11:04:34 +0200 Subject: [PATCH 02/11] 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 29943baaf973ed601c7b387e347cef44bceb9538 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Wed, 6 Sep 2023 16:08:12 +0200 Subject: [PATCH 03/11] fixing note formatting --- modules/ROOT/pages/subscriptions/events.adoc | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index 155d0b38..a43b416b 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` @@ -160,9 +160,9 @@ subscription { Subscriptions to `CREATE_RELATIONSHIP` events listen for newly created relationships to a node of the specified type. [NOTE] -=== +==== This subscription operation is **only** available for types that define relationship fields. -=== +==== == `CREATE_RELATIONSHIP` @@ -175,10 +175,10 @@ These events: * Contain the properties of the nodes connected through the relationship, as well as the properties of the new relationship, if any. [NOTE] -=== +==== Connected nodes that may or may not have previously existed are not covered by this subscription. To subscribe to these nodes' updates, use the xref:subscriptions/events.adoc#_create[`CREATE`] or the xref:subscriptions/events.adoc#_update[`UPDATE`] subscription. -=== +==== Subscriptions to `CREATE_RELATIONSHIP` events can be made with the top-level subscription `[type]RelationshipCreated`, which contains the following fields: @@ -192,10 +192,10 @@ While any event unrelated to `relationshipFieldName` should be `null`, the ones Only top-level properties, without relationships, are available and they are the properties that already existed before the `CREATE_RELATIONSHIP` operation took place. [NOTE] -=== +==== Irrespective of the relationship direction in the database, the `CREATE_RELATIONSHIP` event is bound to the type targeted for the subscription. Consequently, if types A and B have xref:subscriptions/events.adoc#create-non-reciprocal-relationships[non-reciprocal relationships] and a GraphQL operation creates a relationship between them (despite being already previously connected in the database), the `CREATE_RELATIONSHIP` event should only return the subscription to the type A. -=== +==== As an example, consider the following type definitions: @@ -1007,10 +1007,10 @@ This object should be populated with properties according to the deleted relatio * Contains the properties of the nodes connected through the relationship, as well as the properties of the newly deleted relationship, if any. [NOTE] -=== +==== Disconnected nodes that may or may not have been deleted in the process are not covered by this subscription. To subscribe to these nodes' updates, use the `DELETE` subscriptions. -=== +==== Subscriptions to `DELETE_RELATIONSHIP` events can be made with the top-level subscription `[type]RelationshipDeleted`, which contains the following fields: @@ -1023,10 +1023,10 @@ While any event unrelated to `relationshipFieldName` should be `null`, the ones Only top-level properties, without relationships, are available and they are the properties that already existed before the `DELETE_RELATIONSHIP` operation took place. [NOTE] -=== +==== Irrespective of the relationship direction in the database, the `DELETE_RELATIONSHIP` event is bound to the type targeted for the subscription. Consequently, if types A and B have xref:subscriptions/events.adoc#delete-non-reciprocal-relationships[non-reciprocal relationships] and a GraphQL operation deletes a relationship between them (despite being already previously diconnected in the database), the `DELETE_RELATIONSHIP` event should only return the subscription to the type A. -=== +==== As an example, consider these type definitions: From a82aba222cd9663b03b9b52d877d58669e5385ac 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 04/11] 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 | 27 +-- 6 files changed, 683 insertions(+), 27 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 a43b416b..d0a856de 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -10,36 +10,11 @@ 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 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: - -* `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` - 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. From 68a3446212d8bdf006e9f8e53c55e61ae325eec9 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Tue, 5 Sep 2023 15:34:54 +0200 Subject: [PATCH 05/11] 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 804f1686cd760d061ac86ac3ecfc41b42c0e362a Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Wed, 6 Sep 2023 16:08:12 +0200 Subject: [PATCH 06/11] 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 6f94940b65c6abc8af5c5e730786019b54dc9520 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Tue, 5 Sep 2023 15:34:54 +0200 Subject: [PATCH 07/11] Editorial review of the most recent changes --- .../ROOT/pages/authentication-and-authorization/index.adoc | 1 + modules/ROOT/pages/integrations/apollo-federation.adoc | 1 + modules/ROOT/pages/subscriptions/events.adoc | 4 ++-- 3 files changed, 4 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/integrations/apollo-federation.adoc b/modules/ROOT/pages/integrations/apollo-federation.adoc index bd67965e..5011d2a4 100644 --- a/modules/ROOT/pages/integrations/apollo-federation.adoc +++ b/modules/ROOT/pages/integrations/apollo-federation.adoc @@ -1,4 +1,5 @@ [[apollo-federation]] +:description: This guide shows how to create a subgraph using the Neo4j GraphQL Library. = Apollo Federation :page-aliases: guides/apollo-federation.adoc :description: This guide shows how to create a subgraph using the Neo4j GraphQL Library, for composition into a supergraph using Apollo Federation. 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 041b1105adbb08ce7afb430bd70056ca9cd1db07 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Wed, 6 Sep 2023 16:08:12 +0200 Subject: [PATCH 08/11] 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 516a5ebf7a4a25f171b0014c055a31446beeddc1 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 09/11] 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 0e8e3335b566bae30481d7ac9edfb2086f39e4d7 Mon Sep 17 00:00:00 2001 From: lidiazuin Date: Tue, 5 Sep 2023 15:34:54 +0200 Subject: [PATCH 10/11] 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 eb403e46903831c2ac7716010f370f1f337faa13 Mon Sep 17 00:00:00 2001 From: Darrell Warde <8117355+darrellwarde@users.noreply.github.com> Date: Tue, 26 Sep 2023 13:08:11 +0100 Subject: [PATCH 11/11] Fix scalar description placeholders (#38) --- modules/ROOT/pages/type-definitions/types/scalar.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ROOT/pages/type-definitions/types/scalar.adoc b/modules/ROOT/pages/type-definitions/types/scalar.adoc index 67315112..c3f40b20 100644 --- a/modules/ROOT/pages/type-definitions/types/scalar.adoc +++ b/modules/ROOT/pages/type-definitions/types/scalar.adoc @@ -43,7 +43,7 @@ query { ---- | `Float` -| Placeholder text to make the table prettier. +| Represents signed double‐precision fractional values. a| [source, graphql, indent=0] ---- @@ -63,7 +63,7 @@ type Product { ---- | `Boolean` -| Placeholder text to make the table prettier. +| Represents `true` or `false`. a| [source, graphql, indent=0] ---- @@ -80,4 +80,4 @@ type Product { id: ID! } ---- -|=== \ No newline at end of file +|===