GraphQL quick start
At the end of this guide, you will have created a simple GraphQL application that connects to the Memgraph database and executes simple queries against it.
Quickstart
We’ll be using a simple Node.js application using the Neo4j GraphQL Library to connect to a running Memgraph instance and execute GraphQL queries against the database.
Necessary prerequisites that should be installed in your local environment are:
Run Memgraph
If you’re new to Memgraph or you’re in a developing stage, we recommend using the Memgraph Platform. Besides the database, it also includes all the tools you might need to analyze your data, such as command-line interface mgconsole, web interface Memgraph Lab and a complete set of algorithms within a MAGE library.
Ensure Docker is running in the background. Depending on your operating system, execute the appropriate command in the console:
For Linux and macOS:
curl https://install.memgraph.com | sh
For Windows:
iwr https://windows.memgraph.com | iex
The command above will start Memgraph Platform, which includes Memgraph database, Memgraph Lab and Memgraph MAGE. Memgraph uses Bolt protocol to communicate with the client using the exposed 7687 port. Memgraph Lab is a web application you can use to visualize the data. It’s accessible at http://localhost:3000 if Memgraph Platform is running correctly. The 7444 port enables Memgraph Lab to access and preview the logs, which is why both of these ports need to be exposed.
For more information visit the getting started guide on how to run Memgraph with Docker.
Create a work directory
Next, create a directory for your project and position yourself in it:
mkdir graphql-example
cd graphql-example
Initialize the Node.js project
Initialize the project using the following code:
npm init es6 --yes
Setup the Neo4j GraphQL Library
Install the library, its dependencies, and a GraphQL server (such as Apollo Server) by running the following command:
npm install @neo4j/graphql@7.2.0 graphql neo4j-driver @apollo/server
Memgraph is currently compatible with @neo4j/graphql@7.2.0
. Other versions of
the GraphQL middleware may not generate Memgraph-compatible queries.
Create the Schema
GraphQL APIs need to be aware of the shape of the data they are working with, which is abstracted into the concept of GraphQL schemas. This must be explicitly specified in the Node.js application file. In terms of a property graph, the schema must contain the labels and properties of nodes and relationships. (Whilst the Neo4j GraphQL Library has support for automatic graph introspection, Memgraph currently does not support this feature.)
More information on defining a GraphQL schema can be found in the GraphQL documentation.
Given the following dataset:
CREATE (u1:User {id: "user1", name: "Alice"})
CREATE (u2:User {id: "user2", name: "Bob"})
CREATE (p1:Post {id: "post1", content: "Alice's first post!"})
CREATE (p2:Post {id: "post2", content: "Bob's great idea."})
CREATE (p3:Post {id: "post3", content: "Another thought from Alice."})
CREATE (u1)-[:HAS_POST]->(p1)
CREATE (u2)-[:HAS_POST]->(p2)
CREATE (u1)-[:HAS_POST]->(p3);
We could create the following schema, where type Post @node
corresponds to a
vertex with a :Post
label, content: String
to a content
property on the
vertex, and :HAS_POST
edges are notated using the @relationship
directive
with type HAS_POST
.
type Post @node {
id: ID! @id
content: String!
creator: [User!]! @relationship(type: "HAS_POST", direction: IN)
}
type User @node {
id: ID! @id
name: String
posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT)
}
Note that relationships in the schema must always be expressed as many-to-many
(i.e, as array [ ]
types), even if they model one-to-one, one-to-many, or
many-to-one relationships. This is a restriction of the GraphQL middleware.
Create the application file
The application file will be used to setup the Neo4j GraphQL Library and connect to the running Memgraph instance.
Create the file:
touch index.js
Add the content below. Note that the schema we created above is used as a
string literal for typeDefs
:
import { Neo4jGraphQL } from "@neo4j/graphql";
import { ApolloServer } from '@apollo/server'
import { startStandaloneServer } from '@apollo/server/standalone';
import neo4j from 'neo4j-driver'
const typeDefs = `
type Post @node {
id: ID! @id
content: String!
creator: [User!]! @relationship(type: "HAS_POST", direction: IN)
}
type User @node {
id: ID! @id
name: String
posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT)
}
`;
const driver = neo4j.driver(
"bolt://localhost:7687",
neo4j.auth.basic("", "")
);
const neoSchema = new Neo4jGraphQL({ typeDefs, driver });
const server = new ApolloServer({
schema: await neoSchema.getSchema(),
});
const { url } = await startStandaloneServer(server, {
context: async ({ req }) => ({
req,
sessionConfig: { database: "memgraph" },
cypherQueryOptions: { addVersionPrefix: false }
}),
listen: { port: 4000 },
});
console.log(`🚀 Server ready at ${url}`);
To set up a GraphQL client against a running Memgraph instance, you have to
specify the GraphQL schema, set up the used drivers, and specify Memgraph as the
used database. Specifying the used database is especially important because the
default database name in the driverConfig
is not compatible with Memgraph.
You must also use cypherQueryOptions: { addVersionPrefix: false }
to ensure
that any Cypher queries are compatible with Memgraph.
Run the application
Run the application using the following code:
node index.js
Interact with Memgraph
You are now ready to interact with Memgraph using GraphQL queries through the
GraphQL server on localhost:4000
or 127.0.0.1:4000
.
Running a GraphQL query on the example dataset, such as:
query Users {
users {
name
posts {
content
}
}
}
will yield the following results:
{
"data": {
"users": [
{
"name": "Alice",
"posts": [
{
"content": "Alice's first post!"
},
{
"content": "Another thought from Alice."
}
]
},
{
"name": "Bob",
"posts": [
{
"content": "Bob's great idea."
}
]
}
]
}
}
Features
Memgraph support includes the following GraphQL features:
- Read queries based on a defined schema.
- Aggregations on nodes and edges.
- Sorting results on any object type defined in the schema.
- Offset and cursor based pagination.
- Create, update, and delete mutations.
- Custom Cypher statements with the
@cypher
directive.
If you encounter serialization errors while using GraphQL client, we recommend referring to our Serialization errors page for detailed guidance on troubleshooting and best practices.