Building a Full-Stack Application with Apache AGE and GraphQL
Tags: apacheage, graphql, graphprocessing, opensource
Published: 2024-06-26 09:43:36

In this blog, we'll look at how to create a full-stack application with Apache AGE as the backend graph database and GraphQL as the API layer. We will go over everything from setting up the environment to building a complete example application. By the end of this blog, you'll have a thorough understanding of how to combine these powerful technologies to build a strong and efficient application.

## 1. Introduction

Apache AGE (A Graph Extension) adds graph database functionality to PostgreSQL, allowing you to take use of graph data structures and queries while remaining in the traditional PostgreSQL environment. GraphQL is an API query language that allows for more flexible and efficient data querying.

Combining Apache AGE and GraphQL allows you to create extremely scalable and efficient apps with complex data relationships. In this blog post, we will create a small application to explain how to integrate these technologies.

## 2. Setting Up Apache AGE

- Installing PostgreSQL
- Installing Apache AGE
- Initializing Apache AGE in PostgreSQL

## 3. Creating the Database Schema
For this example, let's design a social network schema that includes users and relationships.
_Creating Nodes and Relationships_
```
SELECT create_graph('social_network');

-- Creating User nodes
SELECT * FROM cypher('social_network', $$ 
    CREATE (u:User {id: '1', name: 'Alice'})
    CREATE (u:User {id: '2', name: 'Bob'})
    CREATE (u:User {id: '3', name: 'Carol'})
$$) as (v agtype);

-- Creating Friend relationships
SELECT * FROM cypher('social_network', $$ 
    MATCH (a:User), (b:User) 
    WHERE a.id = '1' AND b.id = '2' 
    CREATE (a)-[:FRIEND]->(b)
$$) as (v agtype);
```

## 4. Setting Up a GraphQL Server
_Initializing a Node.js Project_
Create a new directory for your project and initialize a Node.js project:
```
mkdir graphql-age-app
cd graphql-age-app
npm init -y
```
_Installing Dependencies_
Install the necessary packages:
```
npm install express express-graphql graphql pg
```
_Creating the GraphQL Server_
Create a server.js file and set up the GraphQL server:

```
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { buildSchema } = require('graphql');
const { Client } = require('pg');

// Initialize PostgreSQL client
const client = new Client({
    user: 'yourusername',
    host: 'localhost',
    database: 'mydatabase',
    password: 'yourpassword',
    port: 5432,
});

client.connect();

// GraphQL schema
const schema = buildSchema(`
    type User {
        id: ID!
        name: String!
        friends: [User]
    }

    type Query {
        users: [User]
        user(id: ID!): User
    }
`);

// GraphQL root resolver
const root = {
    users: async () => {
        const res = await client.query("SELECT * FROM cypher('social_network', $$ MATCH (u:User) RETURN u $$) as (v agtype)");
        return res.rows.map(row => row.v);
    },
    user: async ({ id }) => {
        const res = await client.query("SELECT * FROM cypher('social_network', $$ MATCH (u:User {id: $1}) RETURN u $$) as (v agtype)", [id]);
        return res.rows[0].v;
    },
};

// Express server setup
const app = express();
app.use('/graphql', graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true,
}));

app.listen(4000, () => console.log('Server is running on http://localhost:4000/graphql'));
```
## 5. Integrating GraphQL with Apache AGE
In the GraphQL resolver, we interact with Apache AGE via SQL queries. You may extend this by including more complex searches and mutations for creating, updating, and deleting nodes and relationships.

**Example Mutation**
Add a mutation to create a user.

```
type Mutation {
    createUser(id: ID!, name: String!): User
}
```
Update the root resolver:

```
const root = {
    // Existing resolvers...

    createUser: async ({ id, name }) => {
        const res = await client.query("SELECT * FROM cypher('social_network', $$ CREATE (u:User {id: $1, name: $2}) RETURN u $$) as (v agtype)", [id, name]);
        return res.rows[0].v;
    },
};
```
## 6. Building the Frontend
Create an index.html file:

```
<!DOCTYPE html>
<html>
<head>
    <title>GraphQL with Apache AGE</title>
</head>
<body>
    <h1>Users</h1>
    <div id="users"></div>

    <script>
        async function fetchUsers() {
            const response = await fetch('http://localhost:4000/graphql', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ query: '{ users { id, name } }' })
            });
            const data = await response.json();
            const usersDiv = document.getElementById('users');
            data.data.users.forEach(user => {
                const userDiv = document.createElement('div');
                userDiv.textContent = `${user.id}: ${user.name}`;
                usersDiv.appendChild(userDiv);
            });
        }

        fetchUsers();
    </script>
</body>
</html>
```
## 7. Conclusion
In this article, we looked at how to create a full-stack application with Apache AGE and GraphQL. We covered how to install Apache AGE, create a GraphQL server, integrate the two, and construct a simple frontend to display data. This sample can be modified to include more features and complicated queries to suit your application's requirements.