Self-hosting GraphQL

This is the documentation of the GraphQL Library version 7. For the long-term support (LTS) version 5, refer to GraphQL Library version 5 LTS.

This tutorial shows you how to:

  • Install the Neo4j GraphQL Library and its dependencies.

  • Set type definitions that represent the structure of your graph database.

  • Start an instance of the library to generate a GraphQL schema.

  • Run an instance of a server to execute queries and mutations against your schema.

Prerequisites

  • The tutorial assumes familiarity with the command line and JavaScript.

  • Make sure that you have Node.js 20+ installed.

  • The examples use the default npm package manager, but you can use other package managers.

  • Set up a Neo4j database. Make sure it fulfills the requirements, including the necessary plugins.

Set up a directory

  1. Create a new directory and cd into it:

    mkdir neo4j-graphql-example
    cd neo4j-graphql-example
  2. Create a new Node.js project (with ESM modules enabled by using the es6 option):

    npm init es6 --yes
  3. Create an empty index.js file which will contain all of the code for this tutorial:

    touch index.js

Install dependencies

Install the Neo4j GraphQL Library and its dependencies with:

npm install @neo4j/graphql graphql neo4j-driver @apollo/server
  • @neo4j/graphql is the official Neo4j GraphQL Library package. It takes your GraphQL type definitions and generates a schema backed by a Neo4j database.

  • graphql is the package used to generate a schema and execute queries and mutations.

  • neo4j-driver is the official Neo4j Driver package for JavaScript, of which an instance must be passed into the Neo4j GraphQL Library.

Install a GraphQL server package to host your schema and allow the execution of queries and mutations against it. The @apollo/server is the default package for Apollo Server.

Add GraphQL type definitions

The Neo4j GraphQL Library is driven by type definitions which map to the nodes and relationships in your Neo4j database. Open the file index.js from Set up a directory in your editor and paste the following type definitions alongside the necessary package imports:

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import { Neo4jGraphQL } from "@neo4j/graphql";
import neo4j from "neo4j-driver";

const typeDefs = `#graphql
    type Product @node {
        productName: String
        category: [Category!]! @relationship(type: "PART_OF", direction: OUT)
    }

    type Category @node {
        categoryName: String
        products: [Product!]! @relationship(type: "PART_OF", direction: IN)
    }
`;

These type definitions only define the node labels "Product" and "Category", and a relationship "PART_OF" between the two. When the schema has been generated, you can execute queries for products and category to read data from the database.

Note that you can alternatively generate type definitions automatically from an existing database by introspecting the schema.

Create an instance of Neo4jGraphQL

For a database located at the default "neo4j://localhost:7687" (see more about port configuration), with the username "username" and the password "password", add the following to the bottom of your index.js file:

const driver = neo4j.driver(
    "neo4j://localhost:7687",
    neo4j.auth.basic("username", "password")
);

const neoSchema = new Neo4jGraphQL({ typeDefs, driver });

Hardcoding your credentials like this is not advisable because it exposes them to anyone who can access your source code. In a real application, protect your credentials.

Create an instance of ApolloServer

To create an Apollo Server instance using the generated schema, in which you can execute queries against it, add the following to the bottom of index.js:

const server = new ApolloServer({
    schema: await neoSchema.getSchema(),
});

const { url } = await startStandaloneServer(server, {
    listen: { port: 4000 },
});

console.log(`🚀 Server ready at ${url}`);

Start the server

Make sure that your index.js file looks like this full example:

import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import { Neo4jGraphQL } from "@neo4j/graphql";
import neo4j from "neo4j-driver";

const typeDefs = `#graphql
    type Product @node {
        productName: String
        category: [Category!]! @relationship(type: "PART_OF", direction: OUT)
    }

    type Category @node {
        categoryName: String
        products: [Product!]! @relationship(type: "PART_OF", direction: IN)
    }
`;

const driver = neo4j.driver(
    "neo4j://localhost:7687",
    neo4j.auth.basic("username", "password")
);

const neoSchema = new Neo4jGraphQL({ typeDefs, driver });

const server = new ApolloServer({
    schema: await neoSchema.getSchema(),
});

const { url } = await startStandaloneServer(server, {
    context: async ({ req }) => ({ req }),
    listen: { port: 4000 },
});

console.log(`🚀 Server ready at ${url}`);

You are ready to start up your GraphQL server. Back in the command line, run:

node index.js

If successful, you should see the following output:

🚀 Server ready at http://localhost:4000/

The address http://localhost:4000/ is the URL where the Apollo Server starts.

Create nodes in the database

  1. Visit http://localhost:4000/ in your web browser. You should get redirected to the Apollo Sandbox.

  2. At the moment your database is empty. To start adding data, copy and paste the following mutation to the Operation panel to create a product and a category in that product:

    mutation {
      createProducts(
        input: [
          {
            productName: "New Product"
            category: { create: [{ node: { categoryName: "New Category" } }] }
          }
        ]
      ) {
        products {
          productName
          category {
            categoryName
          }
        }
      }
    }
  3. Use Run on the top right. You should get the following confirmation that the data has been created in the database in the Response panel:

    {
      "data": {
        "createProducts": {
          "products": [
            {
              "productName": "New Product",
              "category": [
                {
                  "categoryName": "New Category"
                }
              ]
            }
          ]
        }
      }
    }
  4. Query the data you just added. Copy and paste the following query to the Operations panel:

    query {
      products {
        productName
        category {
          categoryName
        }
      }
    }

    Since you only created one "Product" node and one "Category" node, the Response panel shows the following:

    {
      "data": {
        "products": [
          {
            "productName": "New Product",
            "category": [
              {
                "categoryName": "New Category"
              }
            ]
          }
        ]
      }
    }

This concludes the tutorial. You now have a GraphQL API connected to a Neo4j database and you have added two nodes.

To learn more, see Queries and aggregations and Neo4j GraphQL Toolbox. For more advanced database settings, refer to Driver configuration.

Get hands-on with the GraphQL course on GraphAcademy.