In this section, we will explore how to connect a GraphQL server to a database. This is a crucial step in building a functional GraphQL API, as it allows you to fetch and manipulate data stored in a database. We will cover the following topics:

  1. Choosing a Database
  2. Setting Up the Database
  3. Connecting to the Database
  4. Writing Resolvers to Fetch Data
  5. Practical Example
  6. Exercises

  1. Choosing a Database

Before connecting to a database, you need to choose the type of database that best suits your application's needs. Common choices include:

  • SQL Databases: Such as PostgreSQL, MySQL, SQLite.
  • NoSQL Databases: Such as MongoDB, Cassandra.

Comparison Table

Feature SQL Databases NoSQL Databases
Data Model Relational (tables) Document, Key-Value
Schema Fixed schema Flexible schema
Query Language SQL Varies (e.g., MongoDB uses MQL)
Transactions ACID transactions Limited transactions
Scalability Vertical scaling Horizontal scaling

  1. Setting Up the Database

SQL Database (PostgreSQL)

  1. Install PostgreSQL:

    sudo apt-get update
    sudo apt-get install postgresql postgresql-contrib
    
  2. Start PostgreSQL Service:

    sudo service postgresql start
    
  3. Create a Database:

    sudo -u postgres createdb mydatabase
    

NoSQL Database (MongoDB)

  1. Install MongoDB:

    sudo apt-get update
    sudo apt-get install -y mongodb
    
  2. Start MongoDB Service:

    sudo service mongodb start
    
  3. Create a Database: MongoDB automatically creates a database when you insert data into it.

  1. Connecting to the Database

SQL Database (PostgreSQL)

  1. Install pg package:

    npm install pg
    
  2. Create a Connection:

    const { Pool } = require('pg');
    const pool = new Pool({
      user: 'yourusername',
      host: 'localhost',
      database: 'mydatabase',
      password: 'yourpassword',
      port: 5432,
    });
    
    pool.connect((err, client, release) => {
      if (err) {
        return console.error('Error acquiring client', err.stack);
      }
      console.log('Connected to PostgreSQL');
    });
    

NoSQL Database (MongoDB)

  1. Install mongoose package:

    npm install mongoose
    
  2. Create a Connection:

    const mongoose = require('mongoose');
    
    mongoose.connect('mongodb://localhost:27017/mydatabase', {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });
    
    const db = mongoose.connection;
    db.on('error', console.error.bind(console, 'connection error:'));
    db.once('open', function() {
      console.log('Connected to MongoDB');
    });
    

  1. Writing Resolvers to Fetch Data

SQL Database (PostgreSQL)

  1. Define a Resolver:
    const resolvers = {
      Query: {
        users: async () => {
          const client = await pool.connect();
          try {
            const res = await client.query('SELECT * FROM users');
            return res.rows;
          } finally {
            client.release();
          }
        },
      },
    };
    

NoSQL Database (MongoDB)

  1. Define a Resolver:
    const User = mongoose.model('User', new mongoose.Schema({
      name: String,
      age: Number,
    }));
    
    const resolvers = {
      Query: {
        users: async () => {
          return await User.find();
        },
      },
    };
    

  1. Practical Example

Let's create a simple GraphQL server that connects to a PostgreSQL database and fetches user data.

Step-by-Step Example

  1. Install Dependencies:

    npm install express express-graphql graphql pg
    
  2. Create a GraphQL Server:

    const express = require('express');
    const { graphqlHTTP } = require('express-graphql');
    const { buildSchema } = require('graphql');
    const { Pool } = require('pg');
    
    const pool = new Pool({
      user: 'yourusername',
      host: 'localhost',
      database: 'mydatabase',
      password: 'yourpassword',
      port: 5432,
    });
    
    const schema = buildSchema(`
      type User {
        id: ID!
        name: String!
        age: Int!
      }
    
      type Query {
        users: [User]
      }
    `);
    
    const root = {
      users: async () => {
        const client = await pool.connect();
        try {
          const res = await client.query('SELECT * FROM users');
          return res.rows;
        } finally {
          client.release();
        }
      },
    };
    
    const app = express();
    app.use('/graphql', graphqlHTTP({
      schema: schema,
      rootValue: root,
      graphiql: true,
    }));
    
    app.listen(4000, () => console.log('Server running on http://localhost:4000/graphql'));
    
  3. Run the Server:

    node server.js
    
  4. Query the Server: Open your browser and navigate to http://localhost:4000/graphql. Use the following query to fetch users:

    {
      users {
        id
        name
        age
      }
    }
    

  1. Exercises

Exercise 1: Connect to a MongoDB Database

  1. Set up a MongoDB database.
  2. Create a GraphQL server that connects to the MongoDB database.
  3. Write a resolver to fetch data from a MongoDB collection.

Exercise 2: Add a Mutation

  1. Extend the GraphQL schema to include a mutation for adding a new user.
  2. Write a resolver for the mutation.
  3. Test the mutation using GraphiQL.

Solutions

Exercise 1 Solution

  1. Set up MongoDB (Refer to the setup instructions above).
  2. Create a GraphQL Server:
    const express = require('express');
    const { graphqlHTTP } = require('express-graphql');
    const { buildSchema } = require('graphql');
    const mongoose = require('mongoose');
    
    mongoose.connect('mongodb://localhost:27017/mydatabase', {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });
    
    const db = mongoose.connection;
    db.on('error', console.error.bind(console, 'connection error:'));
    db.once('open', function() {
      console.log('Connected to MongoDB');
    });
    
    const User = mongoose.model('User', new mongoose.Schema({
      name: String,
      age: Number,
    }));
    
    const schema = buildSchema(`
      type User {
        id: ID!
        name: String!
        age: Int!
      }
    
      type Query {
        users: [User]
      }
    `);
    
    const root = {
      users: async () => {
        return await User.find();
      },
    };
    
    const app = express();
    app.use('/graphql', graphqlHTTP({
      schema: schema,
      rootValue: root,
      graphiql: true,
    }));
    
    app.listen(4000, () => console.log('Server running on http://localhost:4000/graphql'));
    

Exercise 2 Solution

  1. Extend the GraphQL Schema:

    const schema = buildSchema(`
      type User {
        id: ID!
        name: String!
        age: Int!
      }
    
      type Query {
        users: [User]
      }
    
      type Mutation {
        addUser(name: String!, age: Int!): User
      }
    `);
    
  2. Write a Resolver for the Mutation:

    const root = {
      users: async () => {
        return await User.find();
      },
      addUser: async ({ name, age }) => {
        const user = new User({ name, age });
        await user.save();
        return user;
      },
    };
    
  3. Test the Mutation: Use the following mutation in GraphiQL:

    mutation {
      addUser(name: "John Doe", age: 30) {
        id
        name
        age
      }
    }
    

Conclusion

In this section, we covered how to connect a GraphQL server to both SQL and NoSQL databases. We also learned how to write resolvers to fetch data from these databases. By completing the exercises, you should now have a solid understanding of how to integrate a database with your GraphQL server. In the next section, we will explore data fetching strategies to optimize your GraphQL queries.

© Copyright 2024. All rights reserved