top of page
  • Writer's pictureRevanth Reddy Tondapu

A Step-by-Step Guide to Retrieve Data from Neo4j Database Using Neo4j GraphQL Library and Next.js


Data from Neo4j Database Using Neo4j GraphQL Library and Next.js
Data from Neo4j Database Using Neo4j GraphQL Library and Next.js

Data from Neo4j Database Using Neo4j GraphQL Library and Next.js
Data from Neo4j Database Using Neo4j GraphQL Library and Next.js

Integrating Neo4j with a GraphQL API and displaying the data using Next.js can significantly enhance your application's data retrieval capabilities. This blog post will guide you through setting up this integration step-by-step, ensuring robust authentication and security. We will use the Neo4j GraphQL library for data retrieval and Next.js for displaying the data.


Step 1: Setting Up Your Environment

First, ensure you have Node.js and npm (Node Package Manager) installed. You can download them from the official Node.js website.


Create a New Project

Create a new directory for your project and initialize it with npm:

mkdir neo4j-graphql-nextjs
cd neo4j-graphql-nextjs
npm init -y

Install Required Packages

Install the necessary packages, including apollo-server, neo4j-driver, @neo4j/graphql, and dotenv for managing environment variables.

npm install apollo-server neo4j-driver @neo4j/graphql dotenv

Step 2: Configure Environment Variables

Create a .env file in the root of your project to store your Neo4j database credentials securely.

NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your_password
JWT_SECRET=your_jwt_secret

Step 3: Setting Up Apollo Server with Neo4j GraphQL

Create an index.js file in the root of your project. This file will set up the Apollo Server and connect it to your Neo4j database.


Load Environment Variables

First, load the environment variables using the dotenv package:

// index.js
require('dotenv').config();
const { ApolloServer } = require('apollo-server');
const { Neo4jGraphQL } = require('@neo4j/graphql');
const neo4j = require('neo4j-driver');

const { NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD, JWT_SECRET } = process.env;

Define Your GraphQL Schema

Define a simple GraphQL schema for demonstration purposes. Here, we'll create a schema for User and Post entities.

const typeDefs = `
  type User {
    id: ID!
    name: String!
    posts: [Post] @relationship(type: "HAS_POST", direction: OUT)
  }

  type Post {
    id: ID!
    title: String!
    content: String!
    author: User @relationship(type: "HAS_POST", direction: IN)
  }

  type Query {
    users: [User]
    posts: [Post]
  }
`;

Create a Neo4j Driver Instance

Connect to your Neo4j database using the neo4j-driver package.

const driver = neo4j.driver(NEO4J_URI, neo4j.auth.basic(NEO4J_USERNAME, NEO4J_PASSWORD));

Initialize Neo4jGraphQL

Create an instance of Neo4jGraphQL using the schema and the driver.

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

Create Apollo Server

Create an Apollo Server instance using the Neo4j schema.

const server = new ApolloServer({
  schema: neoSchema.schema,
  context: ({ req }) => {
    // Add authentication logic here
    // For simplicity, we'll skip this in the initial setup
    return { req };
  }
});

Start the Server

Start the Apollo Server.

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});

Your index.js file should look like this:

require('dotenv').config();
const { ApolloServer } = require('apollo-server');
const { Neo4jGraphQL } = require('@neo4j/graphql');
const neo4j = require('neo4j-driver');

const { NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD, JWT_SECRET } = process.env;

const typeDefs = `
  type User {
    id: ID!
    name: String!
    posts: [Post] @relationship(type: "HAS_POST", direction: OUT)
  }

  type Post {
    id: ID!
    title: String!
    content: String!
    author: User @relationship(type: "HAS_POST", direction: IN)
  }

  type Query {
    users: [User]
    posts: [Post]
  }
`;

const driver = neo4j.driver(NEO4J_URI, neo4j.auth.basic(NEO4J_USERNAME, NEO4J_PASSWORD));

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

const server = new ApolloServer({
  schema: neoSchema.schema,
  context: ({ req }) => {
    // Add authentication logic here
    return { req };
  }
});

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});

Step 4: Implement Authentication

For authentication, we'll use JSON Web Tokens (JWT). Install the jsonwebtoken package:

npm install jsonwebtoken

Create Authentication Middleware

Create a new file called auth.js to handle authentication.

// auth.js
const jwt = require('jsonwebtoken');
const { JWT_SECRET } = process.env;

const authenticate = (req) => {
  const token = req.headers.authorization || '';
  try {
    const user = jwt.verify(token, JWT_SECRET);
    return user;
  } catch (e) {
    throw new Error('Authentication failed');
  }
};

module.exports = { authenticate };

Update Apollo Server Context

Update the Apollo Server context to include the authentication logic.

// index.js
// ... previous code ...

const { authenticate } = require('./auth');

const server = new ApolloServer({
  schema: neoSchema.schema,
  context: ({ req }) => {
    const user = authenticate(req);
    return { req, user };
  }
});

// ... previous code ...

Step 5: Create REST API Endpoints

While GraphQL is great, some use cases might require REST endpoints. Let's create a simple REST API using Express.

Install Express

Install Express and CORS middleware:

npm install express cors

Set Up Express Server

Create a new file called rest.js to set up the Express server.

// rest.js
const express = require('express');
const cors = require('cors');
const { ApolloServer } = require('apollo-server-express');
const { Neo4jGraphQL } = require('@neo4j/graphql');
const neo4j = require('neo4j-driver');
require('dotenv').config();

const { NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD, JWT_SECRET } = process.env;
const { authenticate } = require('./auth');

const typeDefs = `
  type User {
    id: ID!
    name: String!
    posts: [Post] @relationship(type: "HAS_POST", direction: OUT)
  }

  type Post {
    id: ID!
    title: String!
    content: String!
    author: User @relationship(type: "HAS_POST", direction: IN)
  }

  type Query {
    users: [User]
    posts: [Post]
  }
`;

const driver = neo4j.driver(NEO4J_URI, neo4j.auth.basic(NEO4J_USERNAME, NEO4J_PASSWORD));
const neoSchema = new Neo4jGraphQL({ typeDefs, driver });

const app = express();
app.use(cors());
app.use(express.json());

const server = new ApolloServer({
  schema: neoSchema.schema,
  context: ({ req }) => {
    const user = authenticate(req);
    return { req, user };
  }
});

server.applyMiddleware({ app, path: '/graphql' });

app.get('/api/users', async (req, res) => {
  const session = driver.session();
  try {
    const result = await session.run('MATCH (u:User) RETURN u');
    const users = result.records.map(record => record.get('u').properties);
    res.json(users);
  } catch (error) {
    res.status(500).json({ error: error.message });
  } finally {
    await session.close();
  }
});

app.listen({ port: 4000 }, () => {
  console.log(`Server ready at http://localhost:4000${server.graphqlPath}`);
});

Run the Express Server

Update your package.json scripts to include a start script:

"scripts": {
  "start": "node rest.js"
}

Run the server:

npm start

Step 6: Set Up Next.js

Now, let's set up a Next.js application to display the data.


Create a New Next.js Application

Navigate to the root of your project and create a new Next.js app:

npx create-next-app client
cd client

Install Apollo Client

Install the Apollo Client and GraphQL packages:

npm install @apollo/client graphql

Set Up Apollo Client

Create a new file called apollo-client.js in the client directory to configure the Apollo Client:

// client/apollo-client.js
import { ApolloClient, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache(),
});

export default client;

Fetch Data in Next.js Pages

Now, let's create a page to fetch and display data from the GraphQL API.


Create a Users Page

Create a new file called users.js in the pages directory:

// client/pages/users.js
import { gql, useQuery } from '@apollo/client';
import client from '../apollo-client';

const GET_USERS = gql`
  query GetUsers {
    users {
      id
      name
      posts {
        id
        title
      }
    }
  }
`;

const Users = () => {
  const { loading, error, data } = useQuery(GET_USERS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <div>
      <h1>Users</h1>
      <ul>
        {data.users.map((user) => (
          <li key={user.id}>
            {user.name}
            <ul>
              {user.posts.map((post) => (
                <li key={post.id}>{post.title}</li>
              ))}
            </ul>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default Users;

Fetch Data at Build Time

To fetch the data at build time using Next.js, you can use the getStaticProps function:

// client/pages/users.js
import { gql } from '@apollo/client';
import client from '../apollo-client';

const GET_USERS = gql`
  query GetUsers {
    users {
      id
      name
      posts {
        id
        title
      }
    }
  }
`;

const Users = ({ users }) => {
  return (
    <div>
      <h1>Users</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>
            {user.name}
            <ul>
              {user.posts.map((post) => (
                <li key={post.id}>{post.title}</li>
              ))}
            </ul>
          </li>
        ))}
      </ul>
    </div>
  );
};

export async function getStaticProps() {
  const { data } = await client.query({
    query: GET_USERS,
  });

  return {
    props: {
      users: data.users,
    },
    revalidate: 10, // In seconds
  };
}

export default Users;

Run Next.js Application

Navigate to the client directory and start the Next.js development server:

npm run dev

Open your browser and navigate to http://localhost:3000/users to see the list of users and their posts fetched from the Neo4j database via the GraphQL API.


Conclusion

By following these steps, you have successfully integrated Neo4j with a GraphQL API using the Neo4j GraphQL library and displayed the data using Next.js. This setup ensures robust data retrieval capabilities with authentication and security measures in place.

Recap of Steps:

  1. Set Up Your Environment: Create a new project and install required packages.

  2. Configure Environment Variables: Securely store your Neo4j credentials.

  3. Set Up Apollo Server with Neo4j GraphQL: Define your GraphQL schema and connect to Neo4j.

  4. Implement Authentication: Secure your API with JWT authentication.

  5. Create REST API Endpoints: Set up an Express server to serve REST endpoints.

  6. Set Up Next.js: Create a Next.js application to fetch and display data.

This integration provides a powerful way to manage and display data, leveraging the strengths of Neo4j's graph database and the flexibility of GraphQL and Next.js. Happy coding!

27 views0 comments

Comments


bottom of page