This is an introduction to the Neo4j GraphQL mapping library (@neo4j/graphql). It also outlines requirements and where to get support. If you are already familiar with @neo4j/graphql, feel free to jump directly to [reference].
@neo4j/graphql 1.0.x at minimum, requires:
-
[Neo4j](https://neo4j.com/) Database 4.1.0 and above.
-
[Apoc](https://neo4j.com/labs/apoc/) 4.1.0 and above
-
Version Control - https://github.com/neo4j/graphql
-
Bug Tracker - https://github.com/neo4j/graphql/issues
GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations. This library makes it easier to use Neo4j and GraphQL together. Translating GraphQL queries into a single Cypher query means users do not need to understand the Cypher Query language & can let the library handle all the database talking.
Using this library users can focus on building great applications while just writing minimal backend code.
Checkout the original Neo4j GraphQL implementation [here](https://grandstack.io/)
When using the new library you will feel right at home, we have taken familiar fundamentals and concepts from neo4j-graphql-js and extended them. This library @neo4j/graphql is a fully supported Neo4j product. Here we look at the changes in the two implementations and also suggest some ways to migrate over to the new library.
The latest and greatest stuff exclusive to this new implementation.
Use nested mutations to perform operations such as; create a post and connect it to an author, with just one GraphQL call leads to ultimately one database trip;
mutation {
createPosts(
input: [
{
title: "nested mutations are cool"
author: { connect: { where: { name: "dan" } } }
}
]
) {
posts {
id
}
}
}
Define complex, nested & related, authorization rules such as; “grant update access to all moderators of a post”.
type User {
id: ID!
username: String!
}
type Post @auth(rules: [
{
allow: [{ moderator: { "id": "$jwt.sub" }}],
operations: ["update"]
}
]) {
id: ID!
title: String!
moderator: User @relationship(type: "MODERATES_POST", direction: "IN")
}
We created an OGM(Object Graph Model) on top of the pre-existing GraphQL work and abstractions. Generate your normal GraphQL schema & use the exposed .model method to receive an instance of a model.
import { OGM } from "@neo4j/graphql";
import * as neo4j from "neo4j/driver";
const typeDefs = `
type Genre {
name: String
}
type Movie {
id: String
name: String
genres: [Genre] @relationship(type: "HAS_GENRE", direction: "OUT")
}
`;
const driver = neo4j.driver("bolt://localhost:7687", neo4j.auth.basic("admin", "password"));
const ogm = new OGM({
typeDefs,
driver,
});
const Movie = ogm.model("Movie"); // Hi I am your model
await Movie.find({ where: { id: "123" } });
// Nested Mutations
await Movie.create({
input: [
{
title: "Saw",
genres: { create: [{ name: "Horror" }] },
},
],
});
Features we have chosen to exclude for the first version of @neo4j/graphql:
We found the existing implementation [here](https://grandstack.io/docs/graphql-relationship-types/), where you have to use the 'top-level' relation directive;
type Rated @relation(name: "RATED") {
....
}
Tricky to reason about. Before adding this feature back in we want to explore some more expressive ideas and take any community feedback on board. The library doesn’t know the concept of relationship properties meaning you cannot; create, read, or filter by properties on a relationship.
In neo4j-graphql-js
users could query top-level Unions such as;
union Search = Genre | Movie
query {
Search {
... on Genre {}
... on Movie {}
}
}
In the new implementation, you cannot do this. We made this decision on the fact that we had to create nodes with multiple labels causing issues.
You can use unions on a @relationship
.
Similar to the reasons states in the Top Level Unions… we found that adding multiple labels onto a node can sometimes cause more problems it’s trying to solve plus if you take into consideration the complexity. In the version, users cannot query top-level Interfaces Nor use them as a @relationship
. In this implementation interfaces give you no real database support therefor no; query, update, delete, filter support. But instead used as a language feature to safeguard your schema. Great for When dealing with repetitive or large schemas you can essentially put "The side railings up".