Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove deprecated label and additonalLabels arguments #2834

Merged
merged 10 commits into from
Feb 6, 2023
6 changes: 6 additions & 0 deletions .changeset/dry-doors-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@neo4j/introspector": major
"@neo4j/graphql": major
---

Deprecated @node directive arguments `label` and `additionalLabels` have been removed. Please use the `labels` argument.
125 changes: 2 additions & 123 deletions docs/modules/ROOT/pages/type-definitions/database-mapping.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,6 @@ The `@node` directive is used to specify the configuration of a GraphQL object t
directive @node(
"""Map the GraphQL type to match Neo4j node labels"""
labels: [String]
"""Map the GraphQL type to a custom Neo4j node label"""
label: String
"""Map the GraphQL type to match additional Neo4j node labels"""
additionalLabels: [String]
"""Allows for the specification of the plural of the type name."""
plural: String
) on OBJECT
----

Expand Down Expand Up @@ -152,45 +146,12 @@ RETURN this { .name } as this
----


==== `label`

NOTE: The label and additionalLabels arguments of the `@node` directive have been deprecated and will be removed in version 4.0.
Please use the xref::type-definitions/database-mapping.adoc#_labels[`labels argument`] instead.

The parameter `label` defines the label to be used in Neo4j instead of the GraphQL type name:

[source, graphql, indent=0]
----
type Movie @node(label: "Film") {
title: String!
}
----

This way, the following query:

[source, graphql, indent=0]
----
{
movies {
title
}
}
----

Generates the cypher query:

[source, cypher, indent=0]
----
MATCH (this: Film)
RETURN this { .title } as this
----

===== Using `$jwt` and `$context`
In some cases, we may want to generate dynamic labels depending on the user requesting. In these cases, we can use the variable `$jwt` to define a custom label define in the JWT (similarly to how it is used in the xref::auth/index.adoc[`@auth` directive]):

[source, graphql, indent=0]
----
type User @node(label: "$jwt.username") {
type User @node(labels: ["$jwt.username"]) {
name: String!
}
----
Expand Down Expand Up @@ -218,7 +179,7 @@ Similarly, context values can be passed directly:

[source, graphql, indent=0]
----
type User @node(label: "$context.appId") {
type User @node(label: ["$context.appId"]) {
name: String!
}
----
Expand All @@ -234,85 +195,3 @@ neoSchema.getSchema().then((schema) => {
});
})
----

==== `additionalLabels`

NOTE: The label and additionalLabels arguments of the `@node` directive have been deprecated and will be removed in version 4.0.
Please use the xref::type-definitions/database-mapping.adoc#_labels[`labels argument`] instead.

`additionalLabels` lets you define extra Neo4j labels that need to exist on the node for that GraphQL type.

[source, graphql, indent=0]
----
type Actor @node(additionalLabels: ["Person", "User"]) {
name: String!
}
----

The following query:

[source, graphql, indent=0]
----
{
Actor {
name
}
}
----

Generates the following cypher query, with the labels `Actor`, `Person` and `User`:

[source, cypher, indent=0]
----
MATCH (this:Actor:Person:User)
RETURN this { .name } as this
----

Note that `additionalLabels` can be used along with `label`:

[source, graphql, indent=0]
----
type Actor @node(label: "ActorDB", additionalLabels: ["Person"]) {
name: String!
}
----

In this case, the resulting Cypher query will use the labels `ActorDB` and `Person` instead of `Actor`:

----
MATCH (this:ActorDB:Person)
RETURN this { .name } as this
----
<<#_using_jwt_and_context,Context and JWT variables>> can be used with `additionalLabels` in the same fashion as in `label`:

[source, graphql, indent=0]
----
type User @node(additionalLabels: ["$jwt.username"]) {
name: String!
}
----

==== `plural`

The parameter `plural` 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.

[source, graphql, indent=0]
----
type Tech @node(plural: "Techs") {
name: String
}
----

This way, instead of the wrongly generated `teches`, the type is properly written as `techs`:

[source, graphql, indent=0]
----
{
techs {
title
}
}
----

The same is applied to other operations such as `createTechs`. Note that database labels will not change.
12 changes: 2 additions & 10 deletions packages/graphql/src/classes/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -304,18 +304,10 @@ class Node extends GraphElement {
}

public getMainLabel(): string {
MacondoExpress marked this conversation as resolved.
Show resolved Hide resolved
return this.nodeDirective?.labels?.[0] || this.nodeDirective?.label || this.name;
return this.nodeDirective?.labels?.[0] || this.name;
}
public getAllLabels(): string[] {
if (!this.nodeDirective) {
return [this.name];
}
if (this.nodeDirective.labels.length) {
return this.nodeDirective.labels;
}
return [this.nodeDirective.label || this.name, ...(this.nodeDirective.additionalLabels || [])];
// TODO: use when removing label & additionalLabels
// return this.nodeDirective?.labels || [this.name];
return this.nodeDirective?.labels || [this.name];
}

public getGlobalIdField(): string {
Expand Down
16 changes: 1 addition & 15 deletions packages/graphql/src/classes/NodeDirective.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,13 @@ import ContextParser from "../utils/context-parser";
import Cypher from "@neo4j/cypher-builder";

export interface NodeDirectiveConstructor {
label?: string;
additionalLabels?: string[];
labels?: string[];
}

export class NodeDirective {
public readonly label: string | undefined;
public readonly additionalLabels: string[];
public readonly labels: string[];

constructor(input: NodeDirectiveConstructor) {
this.label = input.label;
this.additionalLabels = input.additionalLabels || [];
this.labels = input.labels || [];
}

Expand All @@ -48,15 +42,7 @@ export class NodeDirective {
}

public getLabels(typeName: string, context: Context): string[] {
let labels: string[] = [];
if (this.labels.length) {
labels = [...this.labels];
} else {
const mainLabel = this.label || typeName;
labels = [mainLabel, ...this.additionalLabels];
}
// TODO: use when removing label & additionalLabels
// const labels = !this.labels.length ? [typeName] : this.labels;
const labels = !this.labels.length ? [typeName] : this.labels;
return this.mapLabelsWithContext(labels, context);
}

Expand Down
Loading