diff --git a/modules/ROOT/pages/directives/autogeneration.adoc b/modules/ROOT/pages/directives/autogeneration.adoc index 30748457..b18e43ea 100644 --- a/modules/ROOT/pages/directives/autogeneration.adoc +++ b/modules/ROOT/pages/directives/autogeneration.adoc @@ -31,7 +31,7 @@ The following type definition specifies the `id` field as an autogenerated value [source, graphql, indent=0] ---- -type User { +type User @node { id: ID! @id username: String! } @@ -70,7 +70,7 @@ The following type definition has two individual fields to store the timestamps [source, graphql, indent=0] ---- -type User { +type User @node { createdAt: DateTime! @timestamp(operations: [CREATE]) updatedAt: DateTime! @timestamp(operations: [UPDATE]) } @@ -80,14 +80,14 @@ The following two equivalent type definitions have a single field storing the ev [source, graphql, indent=0] ---- -type User { +type User @node { lastModified: DateTime! @timestamp } ---- [source, graphql, indent=0] ---- -type User { +type User @node { lastModified: DateTime! @timestamp(operations: [CREATE, UPDATE]) } ---- diff --git a/modules/ROOT/pages/directives/custom-directives.adoc b/modules/ROOT/pages/directives/custom-directives.adoc index c4c0ae5a..aaf6bcad 100644 --- a/modules/ROOT/pages/directives/custom-directives.adoc +++ b/modules/ROOT/pages/directives/custom-directives.adoc @@ -57,7 +57,7 @@ const neoSchema = new Neo4jGraphQL({ typeDefs: [ upperDirectiveTypeDefs, `#graphql - type Movie { + type Movie @node { name: String @uppercase } `, diff --git a/modules/ROOT/pages/directives/custom-logic.adoc b/modules/ROOT/pages/directives/custom-logic.adoc index 872d48d3..ce7a6199 100644 --- a/modules/ROOT/pages/directives/custom-logic.adoc +++ b/modules/ROOT/pages/directives/custom-logic.adoc @@ -51,7 +51,7 @@ interface Auth { a| You can use the JWT in the request to return the value of the currently logged in User: [source, graphql, indent=0] ---- -type User { +type User @node { id: String } @@ -121,7 +121,7 @@ Both approaches are demonstrated here: [source, graphql, indent=0] ---- -type User { +type User @node { id } @@ -139,7 +139,7 @@ type Query { [source, graphql, indent=0] ---- -type User { +type User @node { id } @@ -189,13 +189,13 @@ In the following example, the field `similarMovies` is bound to the `Movie` type [source, graphql, indent=0] ---- -type Actor { +type Actor @node { actorId: ID! name: String movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) } -type Movie { +type Movie @node { movieId: ID! title: String description: String @@ -220,7 +220,7 @@ The following example demonstrates a query to return all of the actors in the da [source, graphql, indent=0] ---- -type Actor { +type Actor @node { actorId: ID! name: String } @@ -243,7 +243,7 @@ The following example demonstrates a mutation using a Cypher query to insert a s [source, graphql, indent=0] ---- -type Actor { +type Actor @node { actorId: ID! name: String } @@ -295,7 +295,7 @@ enum Status { ACTIVE INACTIVE } -type Movie { +type Movie @node { status: Status @coalesce(value: ACTIVE) } ---- @@ -350,7 +350,7 @@ Take, for instance, this schema: [source, javascript, indent=0] ---- const typeDefs = ` - type User { + type User @node { firstName: String! lastName: String! fullName: String! @customResolver(requires: "firstName lastName") @@ -402,13 +402,13 @@ Using a selection set string makes it possible to select fields from related typ [source, javascript, indent=0] ---- const typeDefs = ` - type Address { + type Address @node { houseNumber: Int! street: String! city: String! } - type User { + type User @node { id: ID! firstName: String! lastName: String! @@ -442,7 +442,7 @@ interface Publication { publicationYear: Int! } -type Author { +type Author @node { name: String! publications: [Publication!]! @relationship(type: "WROTE", direction: OUT) publicationsWithAuthor: [String!]! @@ -451,13 +451,13 @@ type Author { ) } -type Book implements Publication { +type Book implements Publication @node { title: String! publicationYear: Int! author: [Author!]! @relationship(type: "WROTE", direction: IN) } -type Journal implements Publication { +type Journal implements Publication @node { subject: String! publicationYear: Int! author: [Author!]! @relationship(type: "WROTE", direction: IN) @@ -473,7 +473,7 @@ interface Publication { publicationYear: Int! } -type Author { +type Author @node { name: String! publications: [Publication!]! @relationship(type: "WROTE", direction: OUT) publicationsWithAuthor: [String!]! @@ -482,13 +482,13 @@ type Author { ) } -type Book implements Publication { +type Book implements Publication @node { title: String! publicationYear: Int! author: [Author!]! @relationship(type: "WROTE", direction: IN) } -type Journal implements Publication { +type Journal implements Publication @node { subject: String! publicationYear: Int! author: [Author!]! @relationship(type: "WROTE", direction: IN) @@ -530,7 +530,7 @@ Type definitions: [source, graphql, indent=0] ---- -type Product { +type Product @node { name: String! slug: String! @populatedBy(callback: "slug", operations: [CREATE, UPDATE]) } @@ -566,7 +566,7 @@ For example, if you want a field `modifiedBy`: [source, graphql, indent=0] ---- -type Record { +type Record @node { content: String! modifiedBy: @populatedBy(callback: "modifiedBy", operations: [CREATE, UPDATE]) } diff --git a/modules/ROOT/pages/directives/database-mapping.adoc b/modules/ROOT/pages/directives/database-mapping.adoc index f0bf111a..ad882406 100644 --- a/modules/ROOT/pages/directives/database-mapping.adoc +++ b/modules/ROOT/pages/directives/database-mapping.adoc @@ -8,84 +8,26 @@ This page describes how to use directives for database mapping. Each type in your GraphQL type definitions can be mapped to an entity in your Neo4j database, such as nodes, relationships, and relationship properties. -== `@relationship` - -Relationships are represented by marking particular fields with a directive -- in this case, `@relationship`. -It defines the relationship type in the database, as well as which direction that relationship goes in. - -To add a second node type, "Actor", and connect the two together, you should do the following: - -[source, graphql, indent=0] ----- -type Movie { - title: String - actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) -} - -type Actor { - name: String - movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) -} ----- - -Note that, in this case, there is a directive on each "end" of the relationship, but it is not essential. - - -== `@relationshipProperties` - -=== Definition - -[source, graphql, indent=0] ----- -"""Required to differentiate between interfaces for relationship properties, and otherwise.""" -directive @relationshipProperties on OBJECT ----- - -`@relationshipProperties` can only be used on interfaces. - -=== Usage - -In order to add properties to a relationship, add a new type to your type definitions decorated with the `@relationshipProperties` directive. - -For example, for the "ACTED_IN" relationship, add a property "roles": - -[source, graphql, indent=0] ----- -type Movie { - title: String - actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") -} - -type Actor { - name: String - movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") -} - -type ActedIn @relationshipProperties { - roles: [String] -} ----- - -Note that in addition to this type, there is an added key `properties` in the existing `@relationship` directives. -For more information, see xref::/types/relationships.adoc[Type definitions -> Relationships]. - - [[type-definitions-node]] == `@node` -The most basic mapping uses GraphQL type names to map to a Neo4j node label. -For example, to represent a node with the label "Movie" and a single property "title" of type string: +Adding the `@node` directive to your GraphQL type specifies that it represents a Neo4j node. +For example, to represent a Neo4j node with the label "Movie" and a single property "title" of type string: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String } ---- -With the `@node` directive, you have more control over this mapping, and you can specify the configuration of a GraphQL object type which represents a Neo4j node. -It can be appended with the following optional parameters: +[NOTE] +==== +In the current version, it's not required to specify every GraphQL type representing a Neo4j node with the `@node` directive. +In the future, types without the `@node` directive will no longer treated as Neo4j nodes. +==== +When not differently specified, the GraphQL type name is used as a label for the represented Neo4j node. It's possible to explicitly define the Neo4j node labels by using the argument `labels`: [discrete] === `labels` @@ -216,6 +158,67 @@ await startStandaloneServer(server, { }); ---- +== `@relationship` + +Relationships are represented by marking particular fields with a directive -- in this case, `@relationship`. +It defines the relationship type in the database, as well as which direction that relationship goes in. + +To add a second node type, "Actor", and connect the two together, you should do the following: + +[source, graphql, indent=0] +---- +type Movie @node { + title: String + actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) +} + +type Actor @node { + name: String + movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) +} +---- + +Note that, in this case, there is a directive on each "end" of the relationship, but it is not essential. + + +== `@relationshipProperties` + +=== Definition + +[source, graphql, indent=0] +---- +"""Required to differentiate between interfaces for relationship properties, and otherwise.""" +directive @relationshipProperties on OBJECT +---- + +`@relationshipProperties` can only be used on interfaces. + +=== Usage + +In order to add properties to a relationship, add a new type to your type definitions decorated with the `@relationshipProperties` directive. + +For example, for the "ACTED_IN" relationship, add a property "roles": + +[source, graphql, indent=0] +---- +type Movie @node { + title: String + actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") +} + +type Actor @node { + name: String + movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") +} + +type ActedIn @relationshipProperties { + roles: [String] +} +---- + +Note that in addition to this type, there is an added key `properties` in the existing `@relationship` directives. +For more information, see xref::/types/relationships.adoc[Type definitions -> Relationships]. + [[type-definitions-alias]] == `@alias` @@ -227,7 +230,7 @@ For example: [source, graphql, indent=0] ---- -type User { +type User @node { id: ID! @id @alias(property: "dbId") username: String! } @@ -235,13 +238,13 @@ type User { [source, graphql, indent=0] ---- -type User { +type User @node { id: ID! @id username: String! @alias(property: "dbUserName") livesIn: [City!]! @relationship(direction: OUT, type: "LIVES_IN", properties: "UserLivesInProperties") } -type City { +type City @node { name: String } @@ -251,4 +254,4 @@ type UserLivesInProperties @relationshipProperties { ---- [NOTE] -The property in aliases are automatically escaped (wrapped with backticks ``), so there is no need to add escape characters around them. \ No newline at end of file +The property in aliases are automatically escaped (wrapped with backticks ``), so there is no need to add escape characters around them. diff --git a/modules/ROOT/pages/directives/indexes-and-constraints.adoc b/modules/ROOT/pages/directives/indexes-and-constraints.adoc index 9cdbafd5..5e4f9748 100644 --- a/modules/ROOT/pages/directives/indexes-and-constraints.adoc +++ b/modules/ROOT/pages/directives/indexes-and-constraints.adoc @@ -29,7 +29,7 @@ In the following example, a unique constraint is asserted for the label `Colour` [source, graphql, indent=0] ---- -type Colour { +type Colour @node { hexadecimal: String! @unique } ---- @@ -38,7 +38,7 @@ In the next example, a unique constraint with name `unique_colour` is asserted f [source, graphql, indent=0] ---- -type Colour { +type Colour @node { hexadecimal: String! @unique(constraintName: "unique_colour") } ---- @@ -92,7 +92,7 @@ In this example, a `Fulltext` index called "ProductName", for the name `field`, [source, graphql, indent=0] ---- -type Product @fulltext(indexes: [{ indexName: "ProductName", fields: ["name"] }]) { +type Product @fulltext(indexes: [{ indexName: "ProductName", fields: ["name"] }]) @node { name: String! color: Color! @relationship(type: "OF_COLOR", direction: OUT) } @@ -191,7 +191,7 @@ Additionally, it is possible to define a custom query name as part of the `@full [source, graphql, indent=0] ---- -type Product @fulltext(indexes: [{ queryName: "CustomProductFulltextQuery", indexName: "ProductName", fields: ["name"] }]) { +type Product @fulltext(indexes: [{ queryName: "CustomProductFulltextQuery", indexName: "ProductName", fields: ["name"] }]) @node { name: String! color: Color! @relationship(type: "OF_COLOR", direction: OUT) } @@ -230,12 +230,12 @@ This creates two constraints, one for each field decorated with `@id` and `@uniq [source, javascript, indent=0] ---- const typeDefs = `#graphql - type Color { + type Color @node { id: ID! @id hexadecimal: String! @unique } - type Product @fulltext(indexes: [{ indexName: "ProductName", fields: ["name"] }]) { + type Product @fulltext(indexes: [{ indexName: "ProductName", fields: ["name"] }]) @node { name: String! color: Color! @relationship(type: "OF_COLOR", direction: OUT) } @@ -316,7 +316,7 @@ Perform a nearest neighbor search by passing a vector to find nodes with a vecto .Type definition [source, graphql] ---- -type Product @vector(indexes: [{ +type Product @node @vector(indexes: [{ indexName: "productDescriptionIndex", embeddingProperty: "descriptionVector", queryName: "searchByDescription" @@ -399,7 +399,7 @@ See link:https://neo4j.com/docs/cypher-manual/current/genai-integrations/#ai-pro .Type definition [source, graphql] ---- -type Product @vector(indexes: [{ +type Product @node @vector(indexes: [{ indexName: "productDescriptionIndex", embeddingProperty: "descriptionVector", provider: OPEN_AI, # Assuming this is configured in the server diff --git a/modules/ROOT/pages/directives/schema-configuration/field-configuration.adoc b/modules/ROOT/pages/directives/schema-configuration/field-configuration.adoc index 1296b13f..76fa252b 100644 --- a/modules/ROOT/pages/directives/schema-configuration/field-configuration.adoc +++ b/modules/ROOT/pages/directives/schema-configuration/field-configuration.adoc @@ -8,12 +8,12 @@ In case you need to remove fields from a GraphQL Object Type or a GraphQL Input [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String } -type Actor { +type Actor @node { name: String! age: Int actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) @@ -38,12 +38,12 @@ For instance, to hide the field `age` in the Selection Set, you can use the `@se [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String } -type Actor { +type Actor @node { name: String! age: Int @selectable(onRead: false, onAggregate: false) actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) @@ -116,12 +116,12 @@ It is possible to configure this behavior by passing the argument aggregate on t [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String } -type Actor { +type Actor @node { name: String! age: Int actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, aggregate: false) @@ -168,12 +168,12 @@ To disable the nested `CREATE` operation, change the initial type definitions to [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String } -type Actor { +type Actor @node { name: String! age: Int actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, nestedOperations: [UPDATE, DELETE, CONNECT, DISCONNECT, CONNECT_OR_CREATE]) @@ -188,12 +188,12 @@ If instead, no nested operations are required, it is possible to disable all the [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String } -type Actor { +type Actor @node { name: String! age: Int actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, nestedOperations: []) @@ -222,7 +222,7 @@ With the following definition: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String @selectable(onRead: false, onAggregate: true) } @@ -253,7 +253,7 @@ In case you want to remove the `description` field from `MovieAggregateSelection [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String @selectable(onRead: false, onAggregate: false) } @@ -281,12 +281,12 @@ For instance, these type definitions: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String } -type Actor { +type Actor @node { name: String! actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) @@ -329,12 +329,12 @@ With this definition: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String @settable(onCreate: true, onUpdate: false) } -type Actor { +type Actor @node { name: String! actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) @@ -365,12 +365,12 @@ For example: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String } -type Actor { +type Actor @node { name: String! actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) @@ -416,13 +416,13 @@ With this definition: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String @filterable(byValue: false, byAggregate: false) actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) } -type Actor { +type Actor @node { name: String! actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) @@ -485,13 +485,13 @@ For example: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! description: String @filterable(byValue: false, byAggregate: false) actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) @filterable(byValue: false, byAggregate: false) } -type Actor { +type Actor @node { name: String! actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) diff --git a/modules/ROOT/pages/directives/schema-configuration/global-configuration.adoc b/modules/ROOT/pages/directives/schema-configuration/global-configuration.adoc index 7df40eca..4fbcd1f5 100644 --- a/modules/ROOT/pages/directives/schema-configuration/global-configuration.adoc +++ b/modules/ROOT/pages/directives/schema-configuration/global-configuration.adoc @@ -11,12 +11,12 @@ For instance, if you want *to disable all top-level aggregation operations at on [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) } -type Actor { +type Actor @node { name: String movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) } @@ -40,12 +40,12 @@ Take the following type definitions as example: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) } -type Actor @query(read: false, aggregate: true) { +type Actor @node @query(read: false, aggregate: true) { name: String movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) } diff --git a/modules/ROOT/pages/directives/schema-configuration/type-configuration.adoc b/modules/ROOT/pages/directives/schema-configuration/type-configuration.adoc index 674b3f86..28227525 100644 --- a/modules/ROOT/pages/directives/schema-configuration/type-configuration.adoc +++ b/modules/ROOT/pages/directives/schema-configuration/type-configuration.adoc @@ -9,7 +9,7 @@ For example: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String length: Int } @@ -54,7 +54,7 @@ directive @query(read: Boolean! = true, aggregate: Boolean! = false) on OBJECT | .Disable _movies_ and _moviesConnection_ operations [source, graphql, indent=0] ---- -type Movie @query(read: false, aggregate: true) { +type Movie @node @query(read: false, aggregate: true) { title: String length: Int } @@ -63,7 +63,7 @@ type Movie @query(read: false, aggregate: true) { .Disable _moviesAggregate_ operations [source, graphql, indent=0] ---- -type Movie @query(read: true, aggregate: false) { +type Movie @node @query(read: true, aggregate: false) { title: String length: Int } @@ -91,7 +91,7 @@ directive @mutation(operations: [MutationFields!]! = [CREATE, UPDATE, DELETE]) o .Disable Create, Delete, and Update operations for _Movie_ [source, graphql, indent=0] ---- -type Movie @mutation(operations: []) { +type Movie @node @mutation(operations: []) { title: String length: Int } @@ -100,7 +100,7 @@ type Movie @mutation(operations: []) { .Enable only Create operations for _Movie_ [source, graphql, indent=0] ---- -type Movie @mutation(operations: [CREATE]) { +type Movie @node @mutation(operations: [CREATE]) { title: String length: Int } @@ -130,7 +130,7 @@ directive @subscription(events: [SubscriptionFields!]! = [CREATED, UPDATED, DELE .Disable subscriptions for _Movie_ [source, graphql, indent=0] ---- -type Movie @subscription(events: []) { +type Movie @node @subscription(events: []) { title: String length: Int } @@ -139,7 +139,7 @@ type Movie @subscription(events: []) { .Enable only _movieCreated_ subscription for _Movie_ [source, graphql, indent=0] ---- -type Movie @subscription(events: [CREATED]) { +type Movie @node @subscription(events: [CREATED]) { title: String length: Int } @@ -177,7 +177,7 @@ enum Location { EVERYWHERE } -type SomeType { +type SomeType @node { firstLocation: Location! @default(value: HERE) # valid usage secondLocation: Location! @default(value: ELSEWHERE) # invalid usage, will throw an error } @@ -193,7 +193,7 @@ Take this type definition as an example: [source, graphql, indent=0] ---- -type Tech @plural(value: "Techs") { +type Tech @plural(value: "Techs") @node { name: String } ---- diff --git a/modules/ROOT/pages/driver-configuration.adoc b/modules/ROOT/pages/driver-configuration.adoc index fc33273d..dcd65dc2 100644 --- a/modules/ROOT/pages/driver-configuration.adoc +++ b/modules/ROOT/pages/driver-configuration.adoc @@ -22,7 +22,7 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type User { + type User @node { name: String } `; @@ -54,7 +54,7 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type User { + type User @node { name: String } `; @@ -86,7 +86,7 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type User { + type User @node { name: String } `; @@ -119,7 +119,7 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type User { + type User @node { name: String } `; @@ -151,7 +151,7 @@ import { OGM } from "@neo4j/graphql-ogm"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type User { + type User @node { name: String } `; @@ -178,7 +178,7 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type User { + type User @node { name: String } `; @@ -200,7 +200,7 @@ import { OGM } from "@neo4j/graphql-ogm"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type User { + type User @node { name: String } `; @@ -228,7 +228,7 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type User { + type User @node { name: String } `; diff --git a/modules/ROOT/pages/getting-started/index.adoc b/modules/ROOT/pages/getting-started/index.adoc index cc991eb6..2320ba46 100644 --- a/modules/ROOT/pages/getting-started/index.adoc +++ b/modules/ROOT/pages/getting-started/index.adoc @@ -75,12 +75,12 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type Movie { + type Movie @node { title: String actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) } - type Actor { + type Actor @node { name: String movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) } @@ -148,12 +148,12 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type Movie { + type Movie @node { title: String actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) } - type Actor { + type Actor @node { name: String movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) } diff --git a/modules/ROOT/pages/getting-started/toolbox.adoc b/modules/ROOT/pages/getting-started/toolbox.adoc index f12dbf08..6a736819 100644 --- a/modules/ROOT/pages/getting-started/toolbox.adoc +++ b/modules/ROOT/pages/getting-started/toolbox.adoc @@ -25,12 +25,12 @@ If you followed the xref:getting-started/index.adoc[Getting started tutorial], y + [source, graphql, indent=0] ---- -type Actor { +type Actor @node { actedInMovies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) name: String! } -type Movie { +type Movie @node { actorsActedIn: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) title: String! } diff --git a/modules/ROOT/pages/integrations/apollo-federation.adoc b/modules/ROOT/pages/integrations/apollo-federation.adoc index c8da5b98..071d6270 100644 --- a/modules/ROOT/pages/integrations/apollo-federation.adoc +++ b/modules/ROOT/pages/integrations/apollo-federation.adoc @@ -15,7 +15,7 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type User { + type User @node { id: ID! name: String! } @@ -177,7 +177,7 @@ For a set of type definitions to be usable as a subgraph for Federation, they mu const typeDefs = `#graphql extend schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key"]) - type User { + type User @node { id: ID! name: String! } @@ -200,7 +200,7 @@ To achieve that, use the `@key` directive to designate a field (or fields) as a const typeDefs = `#graphql extend schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key"]) - type User @key(fields: "id") { + type User @key(fields: "id") @node { id: ID! name: String! } @@ -231,7 +231,7 @@ import { startStandaloneServer } from "@apollo/server/standalone"; import { Neo4jGraphQL } from "@neo4j/graphql"; const typeDefs = `#graphql - type User @key(fields: "id") { + type User @key(fields: "id") @node { id: ID! name: String! } diff --git a/modules/ROOT/pages/integrations/relay-compatibility.adoc b/modules/ROOT/pages/integrations/relay-compatibility.adoc index 351b5022..045362c2 100644 --- a/modules/ROOT/pages/integrations/relay-compatibility.adoc +++ b/modules/ROOT/pages/integrations/relay-compatibility.adoc @@ -26,7 +26,7 @@ So for example, a type `Book` might have the definition: [source, graphql] ---- -type Book implements Node { +type Book implements Node @node { id: ID! isbn: String! } @@ -51,7 +51,7 @@ You can configure this like so: [source, graphql] ---- -type Book { +type Book @node { isbn: String! @relayId } ---- @@ -60,7 +60,7 @@ When the schema is augmented, this type will be output as: [source, graphql] ---- -type Book implements Node { +type Book implements Node @node { id: ID! isbn: String! } diff --git a/modules/ROOT/pages/mutations/create.adoc b/modules/ROOT/pages/mutations/create.adoc index 4ff25476..66eb7e8e 100644 --- a/modules/ROOT/pages/mutations/create.adoc +++ b/modules/ROOT/pages/mutations/create.adoc @@ -6,13 +6,13 @@ Using the following type definitions: [source, graphql, indent=0] ---- -type Post { +type Post @node { id: ID! @id content: String! creator: User! @relationship(type: "HAS_POST", direction: IN) } -type User { +type User @node { id: ID! @id name: String posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT) @@ -118,12 +118,12 @@ Consider the following type definitions: [source, graphql, indent=0] ---- -type Actor { +type Actor @node { name: String! movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) } -type Movie { +type Movie @node { title: String id: ID! @id @unique actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) diff --git a/modules/ROOT/pages/mutations/delete.adoc b/modules/ROOT/pages/mutations/delete.adoc index 7f318fa0..04d1657a 100644 --- a/modules/ROOT/pages/mutations/delete.adoc +++ b/modules/ROOT/pages/mutations/delete.adoc @@ -8,13 +8,13 @@ Using these type definitions: [source, graphql, indent=0] ---- -type Post { +type Post @node { id: ID! @id content: String! creator: User! @relationship(type: "HAS_POST", direction: IN) } -type User { +type User @node { id: ID! @id name: String posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT) diff --git a/modules/ROOT/pages/mutations/update.adoc b/modules/ROOT/pages/mutations/update.adoc index e014da1f..4cc41736 100644 --- a/modules/ROOT/pages/mutations/update.adoc +++ b/modules/ROOT/pages/mutations/update.adoc @@ -8,13 +8,13 @@ Using these type definitions: [source, graphql, indent=0] ---- -type Post { +type Post @node { id: ID! @id content: String! creator: User! @relationship(type: "HAS_POST", direction: IN) } -type User { +type User @node { id: ID! @id name: String posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT) @@ -171,7 +171,7 @@ Consider the following type definitions, a `Movie` with a property array called [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String tags: [String] } @@ -237,7 +237,7 @@ Similarly, you can have multiple array property fields and update them in the sa [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String tags: [String] moreTags: [String] @@ -326,7 +326,7 @@ Similarly, you can have multiple array property fields and update them in the sa [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String tags: [String] moreTags: [String] @@ -372,7 +372,7 @@ Consider the following type definitions: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String tags: [String] moreTags: [String] @@ -443,13 +443,13 @@ For example, take the following GraphQL schema for a social video platform: [source, graphql, indent=0] ---- -type Video { +type Video @node { id: ID @id views: Int ownedBy: User @relationship(type: "OWN_VIDEO", properties: "OwnVideo", direction: IN) } -type User { +type User @node { id: ID @id ownVideo: [Video!]! @relationship(type: "OWN_VIDEO", properties: "OwnVideo", direction: OUT) } diff --git a/modules/ROOT/pages/ogm/directives.adoc b/modules/ROOT/pages/ogm/directives.adoc index d303fd06..6144a28f 100644 --- a/modules/ROOT/pages/ogm/directives.adoc +++ b/modules/ROOT/pages/ogm/directives.adoc @@ -24,7 +24,7 @@ Given the following type definition: [source, graphql, indent=0] ---- -type User { +type User @node { username: String! email: String! password: String! @private @@ -49,7 +49,7 @@ const driver = neo4j.driver( ); const typeDefs = ` - type User { + type User @node { username: String! email: String! password: String! @private diff --git a/modules/ROOT/pages/ogm/installation.adoc b/modules/ROOT/pages/ogm/installation.adoc index 8a63d75c..e6c6c513 100644 --- a/modules/ROOT/pages/ogm/installation.adoc +++ b/modules/ROOT/pages/ogm/installation.adoc @@ -62,7 +62,7 @@ const driver = neo4j.driver( ); const typeDefs = `#graphql - type User { + type User @node { id: ID @id username: String! password: String! @private @@ -257,7 +257,7 @@ const driver = neo4j.driver( ); const typeDefs = ` - type User { + type User @node { id: ID name: String } diff --git a/modules/ROOT/pages/ogm/reference.adoc b/modules/ROOT/pages/ogm/reference.adoc index 4c0df3ea..93b62948 100644 --- a/modules/ROOT/pages/ogm/reference.adoc +++ b/modules/ROOT/pages/ogm/reference.adoc @@ -42,7 +42,7 @@ a| .Type definition [source, graphql, indent=0] ---- -type User { +type User @node { username: String! } ---- @@ -68,7 +68,7 @@ a| import { OGM, generate } from "@neo4j/graphql-ogm"; const typeDefs = ` - type Movie { + type Movie @node { id: ID name: String } @@ -95,7 +95,7 @@ console.log("Types Generated"); import { OGM, generate } from "@neo4j/graphql-ogm"; const typeDefs = ` - type Movie { + type Movie @node { id: ID name: String } @@ -127,7 +127,7 @@ Given the type definitions saved to the variable `typeDefs` and a valid driver i [source, graphql, indent=0] ---- -type Book { +type Book @node { isbn: String! @unique } ---- diff --git a/modules/ROOT/pages/ogm/selection-set.adoc b/modules/ROOT/pages/ogm/selection-set.adoc index 7efaae5c..cade6ed2 100644 --- a/modules/ROOT/pages/ogm/selection-set.adoc +++ b/modules/ROOT/pages/ogm/selection-set.adoc @@ -42,14 +42,14 @@ Given the following type definition: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { id: ID name: String genres: [Genre!]! @relationship(type: "IN_GENRE", direction: OUT) customCypher: String! @cypher(statement: "RETURN someCustomData") } -type Genre { +type Genre @node { name: String } ---- @@ -86,14 +86,14 @@ const driver = neo4j.driver( ); const typeDefs = ` - type Movie { + type Movie @node { id: ID name: String genres: [Genre!]! @relationship(type: "IN_GENRE", direction: OUT) customCypher: String! @cypher(statement: "RETURN someCustomData") } - type Genre { + type Genre @node { name: String } `; @@ -139,14 +139,14 @@ const driver = neo4j.driver( ); const typeDefs = ` - type Movie { + type Movie @node { id: ID name: String genres: [Genre!]! @relationship(type: "IN_GENRE", direction: OUT) customCypher: String! @cypher(statement: "RETURN someCustomData") } - type Genre { + type Genre @node { name: String } `; diff --git a/modules/ROOT/pages/ogm/subscriptions.adoc b/modules/ROOT/pages/ogm/subscriptions.adoc index a298f994..bc43ac32 100644 --- a/modules/ROOT/pages/ogm/subscriptions.adoc +++ b/modules/ROOT/pages/ogm/subscriptions.adoc @@ -14,7 +14,7 @@ Use the following type definitions: [source, javascript, indent=0] ---- const typeDefs = `#graphql - type User { + type User @node { email: String! password: String! @private } @@ -103,7 +103,7 @@ const driver = neo4j.driver( neo4j.auth.basic("neo4j", "password") ); const typeDefs = ` - type User { + type User @node { email: String! password: String! @private } diff --git a/modules/ROOT/pages/ogm/type-generation.adoc b/modules/ROOT/pages/ogm/type-generation.adoc index 66fdb8a3..b02d745f 100644 --- a/modules/ROOT/pages/ogm/type-generation.adoc +++ b/modules/ROOT/pages/ogm/type-generation.adoc @@ -24,7 +24,7 @@ import * as neo4j from "neo4j-driver" import * as path from "path" const typeDefs = ` - type Movie { + type Movie @node { id: ID name: String } diff --git a/modules/ROOT/pages/queries-aggregations/aggregations.adoc b/modules/ROOT/pages/queries-aggregations/aggregations.adoc index 377f0c12..c4ced6e3 100644 --- a/modules/ROOT/pages/queries-aggregations/aggregations.adoc +++ b/modules/ROOT/pages/queries-aggregations/aggregations.adoc @@ -8,14 +8,14 @@ Quries on this page assume the following type definitions: [source, graphql, indent=0] ---- -type Post { +type Post @node { id: ID! @id content: String! creator: User! @relationship(type: "HAS_POST", direction: IN, properties: "PostedAt") createdAt: DateTime! } -type User { +type User @node { id: ID! @id name: String! age: Int! diff --git a/modules/ROOT/pages/queries-aggregations/filtering.adoc b/modules/ROOT/pages/queries-aggregations/filtering.adoc index f6109f48..6425a4ad 100644 --- a/modules/ROOT/pages/queries-aggregations/filtering.adoc +++ b/modules/ROOT/pages/queries-aggregations/filtering.adoc @@ -117,7 +117,7 @@ const { Neo4jGraphQL } = require("@neo4j/graphql"); const neo4j = require("neo4j-driver"); const typeDefs = ` - type User { + type User @node { name: String } `; @@ -293,13 +293,13 @@ As an example, take these type definitions: [source, graphql, indent=0] ---- -type User { +type User @node { id: ID! name: String posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT) } -type Post { +type Post @node { id: ID! content: String author: User! @relationship(type: "HAS_POST", direction: IN) @@ -389,11 +389,11 @@ Here are some examples on how to apply this kind of filtering: .Schema example [source, graphql, indent=0] ---- -type User { +type User @node { name: String } -type Post { +type Post @node { content: String likes: [User!]! @relationship(type: "LIKES", direction: IN) } @@ -414,12 +414,12 @@ query { .Schema example [source, graphql, indent=0] ---- -type Passenger { +type Passenger @node { name: String age: Int } -type Flight { +type Flight @node { code: String passengers: [Passenger!]! @relationship(type: "FLYING_ON", direction: IN) } @@ -440,12 +440,12 @@ query { .Schema example [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String actors: [Person!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") } -type Person { +type Person @node { name: String } @@ -519,7 +519,7 @@ a| .Type definitions [source, graphql, indent=0] ---- -type Event { +type Event @node { title: String! startTime: DateTime! } @@ -542,7 +542,7 @@ a| .Type definitions [source, graphql, indent=0] ---- -type Event { +type Event @node { title: String! duration: Duration! } diff --git a/modules/ROOT/pages/queries-aggregations/pagination/cursor-based.adoc b/modules/ROOT/pages/queries-aggregations/pagination/cursor-based.adoc index db85f7a4..b004beed 100644 --- a/modules/ROOT/pages/queries-aggregations/pagination/cursor-based.adoc +++ b/modules/ROOT/pages/queries-aggregations/pagination/cursor-based.adoc @@ -9,12 +9,12 @@ Using the following type definition: [source, graphql, indent=0] ---- -type User { +type User @node { name: String! posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT) } -type Post { +type Post @node { content: String! } ---- diff --git a/modules/ROOT/pages/queries-aggregations/pagination/offset-based.adoc b/modules/ROOT/pages/queries-aggregations/pagination/offset-based.adoc index f73d5581..a9892873 100644 --- a/modules/ROOT/pages/queries-aggregations/pagination/offset-based.adoc +++ b/modules/ROOT/pages/queries-aggregations/pagination/offset-based.adoc @@ -8,7 +8,7 @@ Using the following type definition: [source, graphql, indent=0] ---- -type User { +type User @node { name: String! } ---- diff --git a/modules/ROOT/pages/queries-aggregations/queries.adoc b/modules/ROOT/pages/queries-aggregations/queries.adoc index 8697f564..01750e47 100644 --- a/modules/ROOT/pages/queries-aggregations/queries.adoc +++ b/modules/ROOT/pages/queries-aggregations/queries.adoc @@ -8,14 +8,14 @@ Quries on this page assume the following type definitions: [source, graphql, indent=0] ---- -type Post { +type Post @node { id: ID! @id content: String! creator: User! @relationship(type: "HAS_POST", direction: IN, properties: "PostedAt") createdAt: DateTime! } -type User { +type User @node { id: ID! @id name: String! age: Int! diff --git a/modules/ROOT/pages/queries-aggregations/sorting.adoc b/modules/ROOT/pages/queries-aggregations/sorting.adoc index 833b45e7..12042e55 100644 --- a/modules/ROOT/pages/queries-aggregations/sorting.adoc +++ b/modules/ROOT/pages/queries-aggregations/sorting.adoc @@ -10,7 +10,7 @@ Using this example type definition: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! runtime: Int! } @@ -20,7 +20,7 @@ The following sorting input type and query should be generated: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! runtime: Int! } diff --git a/modules/ROOT/pages/security/authentication.adoc b/modules/ROOT/pages/security/authentication.adoc index 3ddedfc7..2055c248 100644 --- a/modules/ROOT/pages/security/authentication.adoc +++ b/modules/ROOT/pages/security/authentication.adoc @@ -11,7 +11,7 @@ Authentication can be configured for an entire type, for example, the type `User [source, graphql, indent=0] ---- -type User @authentication { +type User @authentication @node { id: ID! name: String! password: String! @@ -32,7 +32,7 @@ Additionally, the directive can be configured on a per-field basis, for example: [source, graphql, indent=0] ---- -type User { +type User @node { id: ID! name: String! password: String! @authentication @@ -62,7 +62,7 @@ For instance, to only require authentication for the update or deletion of a use [source, graphql, indent=0] ---- -type User @authentication(operations: [UPDATE, DELETE]) { +type User @authentication(operations: [UPDATE, DELETE]) @node { id: ID! name: String! password: String! @@ -76,7 +76,7 @@ For instance, if it was a requirement that only users with the `admin` role can [source, graphql, indent=0] ---- -type User @authentication(operations: [DELETE], jwt: { roles_INCLUDES: "admin" }) { +type User @authentication(operations: [DELETE], jwt: { roles_INCLUDES: "admin" }) @node { id: ID! name: String! password: String! diff --git a/modules/ROOT/pages/security/authorization.adoc b/modules/ROOT/pages/security/authorization.adoc index adb5aa1b..bda56d86 100644 --- a/modules/ROOT/pages/security/authorization.adoc +++ b/modules/ROOT/pages/security/authorization.adoc @@ -29,11 +29,11 @@ For instance, here is how to filter out `Post` nodes which don't belong to the c [source, graphql, indent=0] ---- -type User { +type User @node { id: ID! } -type Post @authorization(filter: [ +type Post @node @authorization(filter: [ { where: { node: { author: { id: "$jwt.sub" } } } } ]) { title: String! @@ -57,7 +57,7 @@ For instance, to only require filtering for the reading and aggregating posts: [source, graphql, indent=0] ---- -type Post @authorization(filter: [ +type Post @node @authorization(filter: [ { operations: [READ, AGGREGATE] where: { node: { author: { id: "$jwt.sub" } } } } ]) { title: String! @@ -81,7 +81,7 @@ type JWT @jwt { roles: [String!]! } -type User @authorization(validate: [ +type User @node @authorization(validate: [ { where: { node: { id: "$jwt.sub" } } } { where: { jwt: { roles_INCLUDES: "admin" } } } ]) { @@ -106,7 +106,7 @@ For instance, to only require validation for the update or deletion of a post: [source, graphql, indent=0] ---- -type Post @authorization(validate: [ +type Post @node @authorization(validate: [ { operations: [UPDATE, DELETE] where: { node: { author: { id: "$jwt.sub" } } } } ]) { title: String! @@ -125,11 +125,11 @@ For instance, in the case where some `Post` nodes are private and belong to a pa [source, graphql, indent=0] ---- -type User { +type User @node { id: ID! } -type Post @authorization(filter: [ +type Post @node @authorization(filter: [ { where: { node: { author: { id: "$jwt.sub" } } } } { requireAuthentication: false, operations: [READ], where: { node: { public: true } } } ]) { diff --git a/modules/ROOT/pages/security/impersonation-and-user-switching.adoc b/modules/ROOT/pages/security/impersonation-and-user-switching.adoc index 34ec4863..87106091 100644 --- a/modules/ROOT/pages/security/impersonation-and-user-switching.adoc +++ b/modules/ROOT/pages/security/impersonation-and-user-switching.adoc @@ -25,7 +25,7 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type Movie { + type Movie @node { title: String! } `; @@ -69,7 +69,7 @@ import { Neo4jGraphQL, Neo4jGraphQLContext } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type Movie { + type Movie @node { title: String! } `; @@ -123,7 +123,7 @@ import { Neo4jGraphQL } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type Movie { + type Movie @node { title: String! } `; @@ -167,7 +167,7 @@ import { Neo4jGraphQL, Neo4jGraphQLContext } from "@neo4j/graphql"; import neo4j from "neo4j-driver"; const typeDefs = `#graphql - type Movie { + type Movie @node { title: String! } `; diff --git a/modules/ROOT/pages/security/operations.adoc b/modules/ROOT/pages/security/operations.adoc index 70ffa941..73b317de 100644 --- a/modules/ROOT/pages/security/operations.adoc +++ b/modules/ROOT/pages/security/operations.adoc @@ -8,7 +8,7 @@ Each relevant location has a comment such as `CREATE ON OBJECT Movie`, which mea [source, graphql, indent=0] ---- -type Movie @authentication(operations: [CREATE]) { +type Movie @authentication(operations: [CREATE]) @node { title: String! actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) } diff --git a/modules/ROOT/pages/security/subscriptions-authorization.adoc b/modules/ROOT/pages/security/subscriptions-authorization.adoc index cb0490f2..da69784f 100644 --- a/modules/ROOT/pages/security/subscriptions-authorization.adoc +++ b/modules/ROOT/pages/security/subscriptions-authorization.adoc @@ -18,7 +18,7 @@ For instance, here is how to filter out `User` events which don't match the JWT [source, graphql, indent=0] ---- -type User @subscriptionsAuthorization(filter: [ +type User @node @subscriptionsAuthorization(filter: [ { where: { node: { id: "$jwt.sub" } } } ]) { id: ID! @@ -39,7 +39,7 @@ For instance, to only require filtering for mutations to a type itself and not i [source, graphql, indent=0] ---- -type User @subscriptionsAuthorization(filter: [ +type User @node @subscriptionsAuthorization(filter: [ { events: [CREATED, UPDATED, DELETED], where: { node: { id: "$jwt.sub" } } } ]) { id: ID! @@ -55,7 +55,7 @@ For instance, in the case where some `Post` nodes are private whilst other `Post [source, graphql, indent=0] ---- -type Post @subscriptionsAuthorization(filter: [ +type Post @node @subscriptionsAuthorization(filter: [ { requireAuthentication: false, where: { node: { public: true } } } ]) { title: String! diff --git a/modules/ROOT/pages/subscriptions/events.adoc b/modules/ROOT/pages/subscriptions/events.adoc index 40ec2295..473d0109 100644 --- a/modules/ROOT/pages/subscriptions/events.adoc +++ b/modules/ROOT/pages/subscriptions/events.adoc @@ -29,7 +29,7 @@ As an example, consider the following type definitions: [source,graphql,indent=0] ---- -type Movie { +type Movie @node { title: String genre: String } @@ -69,7 +69,7 @@ As an example, consider the following type definitions: [source,graphql,indent=0] ---- -type Movie { +type Movie @node { title: String genre: String } @@ -108,7 +108,7 @@ As an example, consider the following type definitions: [source,graphql,indent=0] ---- -type Movie { +type Movie @node { title: String genre: String } @@ -168,14 +168,14 @@ As an example, consider the following type definitions: [source,graphql,indent=0] ---- -type Movie { +type Movie @node { title: String genre: String actors: [Actor] @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") reviewers: [Reviewer] @relationship(type: "REVIEWED", direction: IN, properties: "Reviewed") } -type Actor { +type Actor @node { name: String } @@ -183,7 +183,7 @@ type ActedIn @relationshipProperties { screenTime: Int! } -type Reviewer { +type Reviewer @node { name: String reputation: Int } @@ -245,13 +245,13 @@ For another example, this time creating a relationship with standard types, cons [source,graphql,indent=0] ---- -type Movie { +type Movie @node { title: String genre: String actors: [Actor] @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") } -type Actor { +type Actor @node { name: String } @@ -295,7 +295,7 @@ As an example, consider the following type definitions: [source,graphql,indent=0] ---- -type Movie { +type Movie @node { title: String genre: String directors: [Director!]! @relationship(type: "DIRECTED", properties: "Directed", direction: IN) @@ -303,11 +303,11 @@ type Movie { union Director = Person | Actor -type Actor { +type Actor @node { name: String } -type Person { +type Person @node { name: String reputation: Int } @@ -354,7 +354,7 @@ For an example in which a relationship is created with an interface, consider th [source,graphql,indent=0] ---- -type Movie { +type Movie @node { title: String genre: String reviewers: [Reviewer!]! @relationship(type: "REVIEWED", properties: "Review", direction: IN) @@ -364,12 +364,12 @@ interface Reviewer { reputation: Int! } -type Magazine implements Reviewer { +type Magazine implements Reviewer @node { title: String reputation: Int! } -type Influencer implements Reviewer { +type Influencer implements Reviewer @node { name: String reputation: Int! } @@ -420,19 +420,19 @@ To illustrate that, consider the following type definitions: [source,graphql,indent=0] ---- -type Movie { +type Movie @node { title: String genre: String actors: [Actor] @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") directors: [Director!]! @relationship(type: "DIRECTED", properties: "Directed", direction: IN) } -type Actor { +type Actor @node { name: String movies: [Movie!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: OUT) } -type Person { +type Person @node { name: String reputation: Int } @@ -704,12 +704,12 @@ type Actor @node(label: "Person") { movies: [Movie!]! @relationship(type: "PART_OF", direction: OUT) } -typePerson { +type Person @node { name: String movies: [Movie!]! @relationship(type: "PART_OF", direction: OUT) } -type Movie { +type Movie @node { title: String genre: String people: [Person!]! @relationship(type: "PART_OF", direction: IN) @@ -999,14 +999,14 @@ As an example, consider these type definitions: [source,graphql,indent=0] ---- -type Movie { +type Movie @node { title: String genre: String actors: [Actor] @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") reviewers: [Reviewer] @relationship(type: "REVIEWED", direction: IN, properties: "Reviewed") } -type Actor {s +type Actor @node { name: String } @@ -1014,7 +1014,7 @@ type ActedIn @relationshipProperties { screenTime: Int! } -type Reviewer { +type Reviewer @node { name: String reputation: Int } @@ -1076,13 +1076,13 @@ As an example, consider these type definitions: [source,graphql,indent=0] ---- -type Movie { +type Movie @node { title: String genre: String actors: [Actor] @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") } -type Actor { +type Actor @node { name: String } @@ -1127,7 +1127,7 @@ Considering the following type definitions: [source, graphql] ---- -type Movie { +type Movie @node { title: String genre: String directors: [Director!]! @relationship(type: "DIRECTED", properties: "Directed", direction: IN) @@ -1135,11 +1135,11 @@ type Movie { union Director = Person | Actor -type Actor { +type Actor @node { name: String } -type Person { +type Person @node { name: String reputation: Int } @@ -1185,7 +1185,7 @@ Considering the following type definitions: [source, graphql] ---- -type Movie { +type Movie @node { title: String genre: String reviewers: [Reviewer!]! @relationship(type: "REVIEWED", properties: "Review", direction: IN) @@ -1195,12 +1195,12 @@ interface Reviewer { reputation: Int! } -type Magazine implements Reviewer { +type Magazine implements Reviewer @node { title: String reputation: Int! } -type Influencer implements Reviewer { +type Influencer implements Reviewer @node { name: String reputation: Int! } @@ -1250,19 +1250,19 @@ Considering the following type definitions: [source, graphql] ---- -type Movie { +type Movie @node { title: String genre: String actors: [Actor] @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") directors: [Director!]! @relationship(type: "DIRECTED", properties: "Directed", direction: IN) } -type Actor { +type Actor @node { name: String movies: [Movie!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: OUT) } -type Person { +type Person @node { name: String reputation: Int } @@ -1562,12 +1562,12 @@ type Actor @node(label: "Person") { movies: [Movie!]! @relationship(type: "PART_OF", direction: OUT) } -typePerson { +typePerson @node { name: String movies: [Movie!]! @relationship(type: "PART_OF", direction: OUT) } -type Movie { +type Movie @node { title: String genre: String people: [Person!]! @relationship(type: "PART_OF", direction: IN) diff --git a/modules/ROOT/pages/subscriptions/filtering.adoc b/modules/ROOT/pages/subscriptions/filtering.adoc index 48321f82..168ead0d 100644 --- a/modules/ROOT/pages/subscriptions/filtering.adoc +++ b/modules/ROOT/pages/subscriptions/filtering.adoc @@ -73,7 +73,7 @@ As an example, consider the following type definitions: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String genre: String averageRating: Float @@ -232,7 +232,7 @@ As an example, in the following type definitions: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String genre: String actors: [Actor!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) @@ -242,7 +242,7 @@ type ActedIn @relationshipProperties { screenTime: Int! } -type Actor { +type Actor @node { name: String } ---- @@ -341,7 +341,7 @@ Considering the following type definitions: [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String genre: String actors: [Actor!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) @@ -353,11 +353,11 @@ type ActedIn @relationshipProperties { screenTime: Int! } -type Actor { +type Actor @node { name: String } -type Person implements Reviewer { +type Person implements Reviewer @node { name: String reputation: Int } @@ -372,12 +372,12 @@ interface Reviewer { reputation: Int! } -type Magazine implements Reviewer { +type Magazine implements Reviewer @node { title: String reputation: Int! } -type Review @relationshipProperties { +type Review @relationshipProperties @node { score: Int! } ---- diff --git a/modules/ROOT/pages/subscriptions/getting-started.adoc b/modules/ROOT/pages/subscriptions/getting-started.adoc index 70ffc4f1..9855dcef 100644 --- a/modules/ROOT/pages/subscriptions/getting-started.adoc +++ b/modules/ROOT/pages/subscriptions/getting-started.adoc @@ -55,11 +55,11 @@ import { useServer } from "graphql-ws/lib/use/ws"; import express from 'express'; const typeDefs = ` - type Movie { + type Movie @node { title: String } - type Actor { + type Actor @node { name: String } `; diff --git a/modules/ROOT/pages/troubleshooting.adoc b/modules/ROOT/pages/troubleshooting.adoc index c5a19cc1..ac1da921 100644 --- a/modules/ROOT/pages/troubleshooting.adoc +++ b/modules/ROOT/pages/troubleshooting.adoc @@ -38,7 +38,7 @@ const neo4j = require("neo4j-driver"); const { ApolloServer } = require("apollo-server"); const typeDefs = ` - type Movie { + type Movie @node { title: String! } `; @@ -84,7 +84,7 @@ const neo4j = require("neo4j-driver"); const { ApolloServer } = require("apollo-server"); const typeDefs = ` - type Movie { + type Movie @node { title: String! } `; @@ -147,7 +147,7 @@ The following example will create inputs with `_emptyInput`: [source, graphql] ---- -type Cookie { +type Cookie @node { id: ID! @id owner: Owner! @relationship(type: "HAS_OWNER", direction: OUT) # f: String # If you don't want _emptyInput, uncomment this line. @@ -160,13 +160,13 @@ Currently, and given the typeDefs below, Neo4j GraphQL will enforce cardinality [source, graphql, indent=0] ---- -type Movie { +type Movie @node { title: String! director: Person! @relationship(type: "DIRECTED", direction: IN) actors: [Person!]! @relationship(type: "ACTED_IN", direction: IN) } -type Person { +type Person @node { name: String! } ---- diff --git a/modules/ROOT/pages/types/interfaces.adoc b/modules/ROOT/pages/types/interfaces.adoc index d691f23b..d3307278 100644 --- a/modules/ROOT/pages/types/interfaces.adoc +++ b/modules/ROOT/pages/types/interfaces.adoc @@ -18,13 +18,13 @@ interface Production { actors: [Actor!]! @declareRelationship } -type Movie implements Production { +type Movie implements Production @node { title: String! actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") runtime: Int! } -type Series implements Production { +type Series implements Production @node { title: String! actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") episodes: Int! @@ -34,7 +34,7 @@ type ActedIn @relationshipProperties { role: String! } -type Actor { +type Actor @node { name: String! actedIn: [Production!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn") } diff --git a/modules/ROOT/pages/types/relationships.adoc b/modules/ROOT/pages/types/relationships.adoc index 1a9096ab..99267948 100644 --- a/modules/ROOT/pages/types/relationships.adoc +++ b/modules/ROOT/pages/types/relationships.adoc @@ -19,12 +19,12 @@ To create that graph using the Neo4j GraphQL Library, first you need to define t [source, graphql, indent=0] ---- -type Person { +type Person @node { name: String! born: Int! } -type Movie { +type Movie @node { title: String! released: Int! } @@ -34,14 +34,14 @@ You can then connect these two types together using `@relationship` directives: [source, graphql, indent=0] ---- -type Person { +type Person @node { name: String! born: Int! actedInMovies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT) directedMovies: [Movie!]! @relationship(type: "DIRECTED", direction: OUT) } -type Movie { +type Movie @node { title: String! released: Int! actors: [Person!]! @relationship(type: "ACTED_IN", direction: IN) @@ -69,14 +69,14 @@ For example, suppose you want to distinguish which roles an actor played in a mo [source, graphql, indent=0] ---- -type Person { +type Person @node { name: String! born: Int! actedInMovies: [Movie!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: OUT) directedMovies: [Movie!]! @relationship(type: "DIRECTED", direction: OUT) } -type Movie { +type Movie @node { title: String! released: Int! actors: [Person!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) @@ -99,19 +99,19 @@ interface Production { actors: [Actor!]! @declareRelationship } -type Actor { +type Actor @node { name: String! born: Int! actedInMovies: [Movie!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: OUT) } -type Movie implements Production { +type Movie implements Production @node { title: String! released: Int! actors: [Actor!]! @relationship(type: "ACTED_IN", properties: "ActedIn", direction: IN) } -type Series implements Production { +type Series implements Production @node { title: String! released: Int! episodes: Int! @@ -131,7 +131,7 @@ To set the default behavior of a relationship when it is queried, you can use th [source, graphql, indent=0] ---- -type Person { +type Person @node { name: String! born: Int! actedInMovies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, queryDirection: DEFAULT_DIRECTED) @@ -315,12 +315,12 @@ For example: [source, graphql, indent=0] ---- -type User { +type User @node { name: String! posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT) } -type Post { +type Post @node { name: String! } ---- diff --git a/modules/ROOT/pages/types/scalar.adoc b/modules/ROOT/pages/types/scalar.adoc index c135c211..6860cc4f 100644 --- a/modules/ROOT/pages/types/scalar.adoc +++ b/modules/ROOT/pages/types/scalar.adoc @@ -17,7 +17,7 @@ The `BigInt` scalar type is an addition specific to the Neo4j database. a| [source, graphql, indent=0] ---- -type Person { +type Person @node { age: Int! } ---- @@ -28,7 +28,7 @@ Shares the same xref::queries-aggregations/filtering.adoc#filtering-numerical-op a| [source, graphql, indent=0] ---- -type File { +type File @node { size: BigInt } ---- @@ -49,7 +49,7 @@ query { a| [source, graphql, indent=0] ---- -type Product { +type Product @node { price: Float! } ---- @@ -59,7 +59,7 @@ type Product { a| [source, graphql, indent=0] ---- -type Product { +type Product @node { name: String! } ---- @@ -69,7 +69,7 @@ type Product { a| [source, graphql, indent=0] ---- -type Product { +type Product @node { inStock: Boolean! } ---- @@ -79,7 +79,7 @@ type Product { a| [source, graphql, indent=0] ---- -type Product { +type Product @node { id: ID! } ---- diff --git a/modules/ROOT/pages/types/spatial.adoc b/modules/ROOT/pages/types/spatial.adoc index e9df8501..c611e116 100644 --- a/modules/ROOT/pages/types/spatial.adoc +++ b/modules/ROOT/pages/types/spatial.adoc @@ -18,7 +18,7 @@ In order to use it in your schema, add a field with a type `Point` to any other [source, graphql, indent=0] ---- -type TypeWithPoint { +type TypeWithPoint @node { location: Point! } ---- @@ -31,7 +31,7 @@ See xref::queries-aggregations/filtering.adoc#_filtering_spatial_types[Filtering [source, graphql, indent=0] ---- -type Point { +type Point @node { latitude: Float! longitude: Float! height: Float @@ -93,7 +93,7 @@ To use it in your schema, add a field with a type `CartesianPoint` to any type(s [source, graphql, indent=0] ---- -type TypeWithCartesianPoint { +type TypeWithCartesianPoint @node { location: CartesianPoint! } ---- @@ -106,7 +106,7 @@ See xref::queries-aggregations/filtering.adoc#_filtering_spatial_types[Filtering [source, graphql, indent=0] ---- -type CartesianPoint { +type CartesianPoint @node { x: Float! y: Float! z: Float diff --git a/modules/ROOT/pages/types/temporal.adoc b/modules/ROOT/pages/types/temporal.adoc index 2f884fdf..d0be0571 100644 --- a/modules/ROOT/pages/types/temporal.adoc +++ b/modules/ROOT/pages/types/temporal.adoc @@ -12,7 +12,7 @@ a| [source, graphql, indent=0] ---- -type User { +type User @node { createdAt: DateTime } ---- @@ -22,7 +22,7 @@ type User { a| [source, graphql, indent=0] ---- -type Movie { +type Movie @node { releaseDate: Date } ---- @@ -37,7 +37,7 @@ Comparisons are made according to the https://neo4j.com/developer/cypher/dates-d a| [source, graphql, indent=0] ---- -type Movie { +type Movie @node { runningTime: Duration! } ---- @@ -47,7 +47,7 @@ type Movie { a| [source, graphql, indent=0] ---- -type Movie { +type Movie @node { nextShowing: LocalDateTime } ---- @@ -57,7 +57,7 @@ type Movie { a| [source, graphql, indent=0] ---- -type Movie { +type Movie @node { nextShowing: Time } ---- @@ -67,7 +67,7 @@ type Movie { a| [source, graphql, indent=0] ---- -type Movie { +type Movie @node { nextShowing: LocalTime } ---- diff --git a/modules/ROOT/pages/types/unions.adoc b/modules/ROOT/pages/types/unions.adoc index 74268600..3161649b 100644 --- a/modules/ROOT/pages/types/unions.adoc +++ b/modules/ROOT/pages/types/unions.adoc @@ -14,16 +14,16 @@ It defines a `User` type that has a relationship `HAS_CONTENT`, of type `[Conten ---- union Content = Blog | Post -type Blog { +type Blog @node { title: String posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT) } -type Post { +type Post @node { content: String } -type User { +type User @node { name: String content: [Content!]! @relationship(type: "HAS_CONTENT", direction: OUT) }