Skip to content

Latest commit

 

History

History
184 lines (131 loc) · 5.41 KB

introduction.adoc

File metadata and controls

184 lines (131 loc) · 5.41 KB

Introduction

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].

Requirements

@neo4j/graphql 1.0.x at minimum, requires:

What is neo4j/graphql ?

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.

Goals of @neo4j/graphql

  • Provide an abstraction for GraphQL developers ontop of Neo4j.

  • Enable the integration with common community library’s and tools.

What’s the difference from neo4j-graphql-js ?

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.

New features

The latest and greatest stuff exclusive to this new implementation.

Nested mutations

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
        }
    }
}

@auth

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")
}

OGM

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" }] },
        },
    ],
});

Excluded features

Features we have chosen to exclude for the first version of @neo4j/graphql:

Relationship Properties

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.

Top level unions

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.

Interface querying

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".

Further Excluded Features

  1. Additional Labels

  2. GraphQL Architect

  3. Indexes and Constraints

  4. Inferring a Schema

  5. Federation Support - We found federation very specific to Apollo users & not beneficial for our greater audience