Mastering GraphQL Server Integration with Node.js and PostgreSQL

In recent years, GraphQL has gained significant traction as a powerful query language for APIs due to its flexibility and efficiency in fetching data. When coupled with Node.js, a versatile JavaScript runtime, and PostgreSQL, a robust open-source relational database, developers can create high-performing, scalable, and maintainable applications. In this blog post, we’ll delve into the integration of GraphQL with Node.js and PostgreSQL, exploring the benefits and providing insights into implementation.

Understanding GraphQL

GraphQL is a query language for APIs and a runtime for executing those queries. Unlike traditional REST APIs, GraphQL enables clients to request only the data they need, reducing over-fetching and under-fetching issues. It allows clients to define the structure of the data they require, providing a more efficient and customized approach to data retrieval.

Prerequisites

Before we begin, ensure you have the following installed on your machine:

  • Node.js and npm (Node Package Manager)
  • PostgreSQL

Related read: What is GraphQL? Learn How GraphQL Is Revolutionizing API Development

Step 1: Setting Up the Project

Let’s start by creating a new Node.js project and installing the necessary dependencies.

mkdir graphql-node-postgresql
cd graphql-node-postgresql
npm init -y
npm install apollo-server graphql pg

Short Description for Package Installed

  1. Apollo-Server: It is a GraphQL server library for Node.js, facilitating the construction of GraphQL APIs.
  2. Graphql: It is the core library for implementing GraphQL functionality in Node.js applications, providing tools for query parsing, schema validation, and data execution.
  3. pg: The PostgreSQL client for Node.js

Step 2: Creating the PostgreSQL Database

Assuming you have PostgreSQL installed and running, let’s create a simple database and a tasks table.

CREATE DATABASE graphql_node_postgresql;
\c graphql_node_postgresql;

CREATE TABLE IF NOT EXISTS public.tasks
(
    id integer NOT NULL,
    name character(250),
    isCompleted boolean DEFAULT false,
    CONSTRAINT tasks_pkey PRIMARY KEY (id)
)

Above step involves creating a PostgreSQL database named “graphql_node_postgresql” and a table named “tasks” within that database. The “tasks” table will have columns for “id” (an integer), “name” (a character string with a maximum length of 250 characters), and “isCompleted” (a boolean indicating whether the task is completed, defaulting to false). The primary key constraint is set on the “id” column to ensure each task has a unique identifier.

Related read: Building Powerful REST APIs with Node.js, Prisma ORM, and PostgreSQL

Step 3: Defining the GraphQL Schema

Now, let’s define the GraphQL schema that represents our data model. Create a file named types.js:

const { gql } = require("apollo-server");

const typeDefs = gql`

type Task {
   id: Int
   name: String
   isCompleted: Boolean
}

type TaskResult {
   id: Int
   message: String
   tasks: [Task]
}

type Mutation {
   task(name: String): TaskResult!
}

type Query {
   tasks: TaskResult!
}

`;

module.exports = typeDefs;

Here’s a breakdown of the code snippet:

  • Use the gql function from the “apollo-server” package to define the schema.
  • Define a “Task” type with fields for ID, name, and completion status (boolean).
  • Define a “TaskResult” type with fields for ID, message, and an array of tasks.
  • Define a “Mutation” type with a mutation named “task” to create a new task, returning a “TaskResult”.
  • Define a “Query” type with a query named “tasks” to fetch tasks, returning a “TaskResult”.

Step 4: Defining the Resolvers for GraphQL

Resolvers are functions responsible for fetching the data for each field defined in the schema. Create a file named resolvers.js to define the resolvers for graphQL:

const pool = require("./db");

const resolvers = {
  Query: {
    tasks: async () => {
      try {
        const result = await pool.query(`SELECT * FROM tasks`);
        return { tasks: result.rows, message: "found" };
      } catch (error) {
        return { message: error.message };
      }
    },
  },

Mutation: {
   task: async (root, args) => {
     try {
       let { name } = args;
       const result = await pool.query(`INSERT INTO tasks (name) 
VALUES ($1)`, [name]);
       return { message: "Task added successfully" };
     } catch (error) {
       return { message: error.message };
     }
    },
   },
};
 
module.exports = resolvers;

Here’s a breakdown of the code snippet:

  • Define an object named “resolvers” containing resolver functions for each field in the schema.
  • Inside the “Query” resolver, implement logic to fetch tasks from the database asynchronously. If successful, return an object containing the fetched tasks and a success message; otherwise, return an error message.
  • Inside the “Mutation” resolver for the “task” mutation, extract the “name” argument from the mutation input and insert a new task into the database. Return a success message upon successful insertion; otherwise, return an error message.

Transform Your API Development with GraphQL. Hire Our Developers Today!

Step 5: Setting Up the PostgreSQL Connection

Create a file named db.js to set up the PostgreSQL connection:

const Pool = require('pg').Pool
const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: 'graphql_node_postgresql',
password: 'postgres',
port: 5432,
})

module.exports = pool;

Step 6: Setting Up the GraphQL Server

Create a file named index.js to set up the GraphQL server:

const { ApolloServer } = require("apollo-server");
const typeDefs = require("./types");
const resolvers = require("./resolver");

const server = new ApolloServer({ typeDefs, resolvers });

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

Here’s a breakdown of the code snippet:

  • Import the ApolloServer class from the “apollo-server” package, which is used to create an instance of the GraphQL server.
  • Import the schema definition (typeDefs) and resolver functions (resolvers) from their respective files (“types.js” and “resolver.js”).
  • Create a new instance of ApolloServer named “server”, passing in the schema definition and resolver functions.
  • Use the listen method of the server instance to start the GraphQL server. This method returns a Promise that resolves to an object containing the server’s URL once the server is ready.

Step 7: Running the Application

node index.js

This command will start the GraphQL server, and it will be ready to accept incoming requests at the specified URL

 (http://localhost:4000/graphql by default).
coma

Conclusion

The integration of GraphQL with Node.js and PostgreSQL offers a powerful and efficient solution for building modern APIs and applications. By utilizing GraphQL’s query flexibility, Node.js’s event-driven architecture, and PostgreSQL’s reliability, developers can create scalable and performant systems while maintaining flexibility and ease of development. Embracing this technology stack empowers developers to meet evolving business needs and deliver exceptional user experiences in today’s dynamic digital landscape.

Keep Reading

Keep Reading

  • Service
  • Career
  • Let's create something together!

  • We’re looking for the best. Are you in?