Integrating Neo4j with Strapi and using Next.js to display the data can significantly enhance your application's data management and retrieval capabilities. This guide walks you through setting up Strapi to use PostgreSQL for user management and Neo4j for CRM data, and how to create custom APIs to access this data. Finally, we’ll use Next.js to fetch and display this data.
Step 1: Create a Strapi Project
Initialize Strapi Project
First, ensure you have Node.js and npm installed. Then, run the following command to create a new Strapi project:
npx create-strapi-app@latest neo4j-strapi --quickstart
This command will create a new Strapi project in the neo4j-strapi directory and start the Strapi server.
Install Required Packages
Navigate to your project directory:
cd neo4j-strapi
Install the necessary packages, including neo4j-driver and @neo4j/graphql:
npm install neo4j-driver @neo4j/graphql
Step 2: Configure Environment Variables
Create a .env file in the root of your Strapi project to store your database credentials securely:
DATABASE_CLIENT=postgres
DATABASE_NAME=strapi
DATABASE_HOST=localhost
DATABASE_PORT=5432
DATABASE_USERNAME=your_postgres_user
DATABASE_PASSWORD=your_postgres_password
NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your_neo4j_password
JWT_SECRET=your_jwt_secret
Step 3: Configure PostgreSQL for User Management
Update Database Configuration
Edit the config/database.js file to use PostgreSQL for user management:
// config/database.js
module.exports = ({ env }) => ({
defaultConnection: 'default',
connections: {
default: {
connector: 'bookshelf',
settings: {
client: 'postgres',
host: env('DATABASE_HOST', 'localhost'),
port: env('DATABASE_PORT', 5432),
database: env('DATABASE_NAME', 'strapi'),
username: env('DATABASE_USERNAME', 'strapi'),
password: env('DATABASE_PASSWORD', 'strapi'),
ssl: env.bool('DATABASE_SSL', false),
},
options: {},
},
},
});
Step 4: Integrate Neo4j GraphQL in Strapi
Load Environment Variables
First, load the environment variables using the dotenv package. Create a new file called database.js in the config directory:
// config/database.js
require('dotenv').config();
const neo4j = require('neo4j-driver');
const { NEO4J_URI, NEO4J_USERNAME, NEO4J_PASSWORD } = process.env;
const driver = neo4j.driver(NEO4J_URI, neo4j.auth.basic(NEO4J_USERNAME, NEO4J_PASSWORD));
module.exports = {
driver,
};
Define Your GraphQL Schema
Create a new file called schema.js in the config directory to define your GraphQL schema:
// config/schema.js
const { Neo4jGraphQL } = require('@neo4j/graphql');
const typeDefs = `
type Person {
id: ID!
name: String!
companies: [Company] @relationship(type: "WORKS_AT", direction: OUT)
}
type Company {
id: ID!
name: String!
employees: [Person] @relationship(type: "WORKS_AT", direction: IN)
}
type Query {
persons: [Person]
companies: [Company]
}
`;
const neoSchema = new Neo4jGraphQL({ typeDefs });
module.exports = {
neoSchema,
};
Integrate Neo4j GraphQL with Strapi
Create a new file called bootstrap.js in the config/functions directory:
// config/functions/bootstrap.js
const { ApolloServer } = require('apollo-server-koa');
const { driver } = require('../database');
const { neoSchema } = require('../schema');
module.exports = async ({ strapi }) => {
const schema = await neoSchema.getSchema();
const server = new ApolloServer({ schema, context: { driver } });
await server.start();
server.applyMiddleware({ app: strapi.server, path: '/graphql' });
};
Step 5: Create Custom API to Access Data from Neo4j
Create a Custom Controller
Create a new file called person.js in the api/person/controllers directory:
// api/person/controllers/person.js
module.exports = {
async find(ctx) {
const session = strapi.config.functions.database.driver.session();
try {
const result = await session.run('MATCH (n:Person) RETURN n');
const records = result.records.map(record => record.get('n').properties);
ctx.send(records);
} catch (err) {
ctx.throw(500, err);
} finally {
session.close();
}
},
};
Define Routes
Create a new file called routes.json in the api/person/config directory:
// api/person/config/routes.json
{
"routes": [
{
"method": "GET",
"path": "/persons",
"handler": "person.find",
"config": {
"policies": []
}
}
]
}
Step 6: Set Up Next.js Project
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
Fetch Data in Next.js Pages
Create a page to fetch and display data from the custom API.
Create a Persons Page
Create a new file called persons.js in the pages directory:
// client/pages/persons.js
import { useEffect, useState } from 'react';
const Persons = () => {
const [persons, setPersons] = useState([]);
useEffect(() => {
const fetchPersons = async () => {
const response = await fetch('http://localhost:1337/persons');
const data = await response.json();
setPersons(data);
};
fetchPersons();
}, []);
return (
<div>
<h1>Persons</h1>
<ul>
{persons.map((person) => (
<li key={person.id}>{person.name}</li>
))}
</ul>
</div>
);
};
export default Persons;
Step 7: Implement Authentication and Security
Securing the GraphQL Endpoint
To secure your GraphQL endpoint, you need to ensure that only authenticated users can access it. Strapi provides middleware to handle authentication.
Create Middleware
Create a new file called auth-middleware.js in the middlewares directory:
// middlewares/auth-middleware.js
module.exports = async (ctx, next) => {
if (ctx.request.header.authorization) {
try {
const token = ctx.request.header.authorization.split(' ')[1];
const decoded = await strapi.plugins['users-permissions'].services.jwt.verify(token);
if (decoded.id) {
ctx.state.user = await strapi.query('user', 'users-permissions').findOne({ id: decoded.id });
}
} catch (err) {
return ctx.unauthorized(`Unauthorized: ${err.message}`);
}
} else {
return ctx.unauthorized('No authorization header found');
}
await next();
};
Step 8: Run Your Applications
Run Strapi
Navigate to the root of your Strapi project and run the Strapi server:
npm run develop
Run Next.js
Navigate to the client directory and start the Next.js development server:
npm run dev
Open your browser and navigate to http://localhost:3000/persons to see the list of persons fetched from the Neo4j database via the custom API.
Conclusion
By following this step-by-step guide, you have successfully set up a robust system that integrates Strapi with a Neo4j database for CRM data management and uses PostgreSQL for user management. You also created custom APIs in Strapi to access this data and displayed it using a Next.js frontend application.
Key Takeaways
Strapi Setup: You configured Strapi to handle different databases for user management and CRM data, enabling a more modular and scalable architecture.
Neo4j Integration: By integrating Neo4j with Strapi using the Neo4j GraphQL library, you leveraged the powerful graph database capabilities to handle complex relationships and queries.
Custom APIs: Creating custom controllers and routes in Strapi allowed you to expose specific data endpoints, giving you fine-grained control over your API.
Next.js Frontend: Using Next.js to fetch and display data from your Strapi API provided a modern, efficient way to build and render your web application.
Authentication and Security: Implementing middleware for authentication ensured that your data endpoints are secure and only accessible to authorized users.
Future Enhancements
Advanced Queries: You can extend the GraphQL schema to include more complex queries and mutations, allowing for richer interactions with your Neo4j data.
Caching and Optimization: Implement caching strategies in both Strapi and Next.js to improve performance, especially for frequently accessed data.
Real-Time Updates: Integrate WebSockets or other real-time technologies to push updates from Neo4j to your Next.js frontend, providing live data updates.
User Roles and Permissions: Enhance the authentication middleware to support different user roles and permissions, providing more granular access control.
Final Thoughts
This setup not only offers a powerful backend to manage and query complex data relationships but also provides a modern frontend to present this data to users effectively. The separation of concerns between user management and CRM data ensures that your application remains scalable and maintainable as it grows.
By leveraging the strengths of Strapi, Neo4j, and Next.js, you have created a flexible and powerful architecture capable of handling a wide range of business requirements. Whether you're building a CRM, a social network, or any other data-intensive application, this stack provides a solid foundation to build upon.
Thank you for following along with this guide. We hope it has been informative and helpful in setting up your project. Happy coding!
Comments