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:
- Choosing a Database
- Setting Up the Database
- Connecting to the Database
- Writing Resolvers to Fetch Data
- Practical Example
- Exercises
- 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 |
- Setting Up the Database
SQL Database (PostgreSQL)
-
Install PostgreSQL:
sudo apt-get update sudo apt-get install postgresql postgresql-contrib
-
Start PostgreSQL Service:
sudo service postgresql start
-
Create a Database:
sudo -u postgres createdb mydatabase
NoSQL Database (MongoDB)
-
Install MongoDB:
sudo apt-get update sudo apt-get install -y mongodb
-
Start MongoDB Service:
sudo service mongodb start
-
Create a Database: MongoDB automatically creates a database when you insert data into it.
- Connecting to the Database
SQL Database (PostgreSQL)
-
Install
pg
package:npm install pg
-
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)
-
Install
mongoose
package:npm install mongoose
-
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'); });
- Writing Resolvers to Fetch Data
SQL Database (PostgreSQL)
- 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)
- Define a Resolver:
const User = mongoose.model('User', new mongoose.Schema({ name: String, age: Number, })); const resolvers = { Query: { users: async () => { return await User.find(); }, }, };
- Practical Example
Let's create a simple GraphQL server that connects to a PostgreSQL database and fetches user data.
Step-by-Step Example
-
Install Dependencies:
npm install express express-graphql graphql pg
-
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'));
-
Run the Server:
node server.js
-
Query the Server: Open your browser and navigate to
http://localhost:4000/graphql
. Use the following query to fetch users:{ users { id name age } }
- Exercises
Exercise 1: Connect to a MongoDB Database
- Set up a MongoDB database.
- Create a GraphQL server that connects to the MongoDB database.
- Write a resolver to fetch data from a MongoDB collection.
Exercise 2: Add a Mutation
- Extend the GraphQL schema to include a mutation for adding a new user.
- Write a resolver for the mutation.
- Test the mutation using GraphiQL.
Solutions
Exercise 1 Solution
- Set up MongoDB (Refer to the setup instructions above).
- 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
-
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 } `);
-
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; }, };
-
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.