# 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:

- The [npm](https://www.npmjs.com/) package manager.
- The [Node.js](https://nodejs.org/en) runtime environment.

### 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](https://memgraph.com/docs/getting-started/cli), web interface [Memgraph
Lab](https://memgraph.com/docs/data-visualization) and a complete set of algorithms within a
[MAGE](https://memgraph.com/docs/advanced-algorithms) library.

Ensure [Docker](https://docs.docker.com/engine/install/) is running in the
background. Depending on your operating system, execute the appropriate command
in the console:

**For Linux and macOS:**

```bash
curl -sSf "https://install.memgraph.com" | sh
```

**For Windows:**

```bash
iwr https://install.memgraph.com/windows -useb | iex
```

The command above will start [Memgraph
Platform](https://memgraph.com/docs/getting-started/install-memgraph/docker#install-memgraph-platform),
which includes [Memgraph
database](https://memgraph.com/docs/getting-started/install-memgraph/docker#other-available-docker-images),
[Memgraph Lab](https://memgraph.com/docs/data-visualization#quick-start) and [Memgraph
MAGE](https://memgraph.com/docs/advanced-algorithms#quick-start). 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](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](https://memgraph.com/docs/getting-started/install-memgraph/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](https://www.apollographql.com/docs/apollo-server/)) by running the
following command:

```
npm install @neo4j/graphql@7.2.0 graphql neo4j-driver @apollo/server
```

> **Warning**
>
> 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](https://graphql.org/learn/schema/).

Given the following dataset:

```cypher
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`.

```graphql
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**
>
> 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`:

```js
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:

```graphql
query Users {
  users {
    name
    posts {
      content
    }
  }
}
```

will yield the following results:

```json
{
  "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.](https://neo4j.com/docs/graphql/current/queries-aggregations/queries/)
- [Aggregations on nodes and edges.](https://neo4j.com/docs/graphql/current/queries-aggregations/aggregations/)
- [Sorting results on any object type defined in the schema.](https://neo4j.com/docs/graphql/current/queries-aggregations/sorting/)
- [Offset and cursor based pagination.](https://neo4j.com/docs/graphql/current/queries-aggregations/pagination/)
- [Create, update, and delete mutations.](https://neo4j.com/docs/graphql/current/mutations/)
- [Custom Cypher statements with the `@cypher` directive.](https://neo4j.com/docs/graphql/current/directives/custom-logic/#_cypher)

> **Info**
>
> If you encounter serialization errors while using GraphQL client, we recommend
> referring to our [Serialization errors](https://memgraph.com/docs/help-center/errors/serialization) page
> for detailed guidance on troubleshooting and best practices.
