DEV Community

Cover image for Building a Basic CRUD Application with GraphQL, React, Node.js, and MongoDB
Arun Kumar
Arun Kumar

Posted on

Building a Basic CRUD Application with GraphQL, React, Node.js, and MongoDB

In today’s web development ecosystem, creating efficient and scalable applications often involves combining powerful technologies. This blog will guide you through building a basic CRUD (Create, Read, Update, Delete) application using GraphQL, React, Node.js, and MongoDB. By the end, you’ll have a clear understanding of how these technologies work together and how to set up your project from scratch.


Why This Tech Stack?

  • GraphQL: A modern API query language that allows clients to request exactly what they need, improving performance and flexibility.
  • Node.js: A JavaScript runtime for building fast, scalable backend applications.
  • MongoDB: A NoSQL database designed for high availability, scalability, and flexibility.
  • React: A powerful JavaScript library for building dynamic user interfaces. This combination ensures you’re using state-of-the-art tools for building a modern web application.

Project Overview

In this project, we’ll create a simple application where users can:

  • Add new items to a database (Create).
  • View all items (Read).
  • Update existing items (Update).
  • Delete items from the database (Delete).

Project Structure

Here is the structure of the project:

├── backend
│   ├── index.js            # Main server file
│   ├── schema.js           # GraphQL schema and resolvers
│   └── models
│       └── Item.js         # MongoDB model
├── frontend
│   ├── src
│   │   ├── App.js          # Main React component
│   │   ├── components
│   │   │   └── ItemList.js # Display list of items
│   │   └── graphql
│   │       ├── queries.js  # GraphQL queries
│   │       └── mutations.js # GraphQL mutations
Enter fullscreen mode Exit fullscreen mode

Prerequisites

Make sure you have the following installed:

  • Node.js (v14 or later)
  • MongoDB

Step 1: Initialize the Backend
Navigate to your desired directory and create a backend folder:

mkdir backend && cd backend
Enter fullscreen mode Exit fullscreen mode

Initialize a Node.js project:

npm init -y
Enter fullscreen mode Exit fullscreen mode

Install the necessary dependencies:

npm install express graphql express-graphql mongoose
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the MongoDB Model
Inside the backend directory, create a folder named models and add a file called Item.js:

const mongoose = require('mongoose');

const ItemSchema = new mongoose.Schema({
  name: { type: String, required: true },
  description: { type: String, required: true },
});

module.exports = mongoose.model('Item', ItemSchema);
Enter fullscreen mode Exit fullscreen mode

Step 3: Define the GraphQL Schema
Create a file named schema.js in the backend directory:

const { GraphQLObjectType, GraphQLSchema, GraphQLString, GraphQLID, GraphQLList } = require('graphql');
const Item = require('./models/Item');

const ItemType = new GraphQLObjectType({
  name: 'Item',
  fields: () => ({
    id: { type: GraphQLID },
    name: { type: GraphQLString },
    description: { type: GraphQLString },
  }),
});

const RootQuery = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: {
    items: {
      type: new GraphQLList(ItemType),
      resolve() {
        return Item.find();
      },
    },
  },
});

const Mutation = new GraphQLObjectType({
  name: 'Mutation',
  fields: {
    addItem: {
      type: ItemType,
      args: {
        name: { type: GraphQLString },
        description: { type: GraphQLString },
      },
      resolve(_, args) {
        const item = new Item({
          name: args.name,
          description: args.description,
        });
        return item.save();
      },
    },
    deleteItem: {
      type: ItemType,
      args: { id: { type: GraphQLID } },
      resolve(_, args) {
        return Item.findByIdAndDelete(args.id);
      },
    },
    updateItem: {
      type: ItemType,
      args: {
        id: { type: GraphQLID },
        name: { type: GraphQLString },
        description: { type: GraphQLString },
      },
      resolve(_, args) {
        return Item.findByIdAndUpdate(
          args.id,
          { name: args.name, description: args.description },
          { new: true }
        );
      },
    },
  },
});

module.exports = new GraphQLSchema({
  query: RootQuery,
  mutation: Mutation,
});
Enter fullscreen mode Exit fullscreen mode

Step 4: Create the Server
Create an index.js file in the backend directory:

const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const mongoose = require('mongoose');
const schema = require('./schema');

const app = express();

mongoose
  .connect('mongodb://localhost:27017/crud-app', { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log('Connected to MongoDB'))
  .catch(err => console.error(err));

app.use('/graphql', graphqlHTTP({
  schema,
  graphiql: true,
}));

app.listen(4000, () => console.log('Server running on http://localhost:4000/graphql'));
Enter fullscreen mode Exit fullscreen mode

Run the server:

node index.js
Enter fullscreen mode Exit fullscreen mode

Setting Up the Frontend

Step 1: Initialize the React App

Navigate to the main directory and create a frontend folder:

npx create-react-app frontend
cd frontend
Enter fullscreen mode Exit fullscreen mode

Install Apollo Client:

npm install @apollo/client graphql
Enter fullscreen mode Exit fullscreen mode

Step 2: Create GraphQL Queries and Mutations
In the src folder, create a graphql folder with two files: queries.js and mutations.js.

queries.js

import { gql } from '@apollo/client';

export const GET_ITEMS = gql`
  query GetItems {
    items {
      id
      name
      description
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

mutations.js

import { gql } from '@apollo/client';

export const ADD_ITEM = gql`
  mutation AddItem($name: String!, $description: String!) {
    addItem(name: $name, description: $description) {
      id
      name
      description
    }
  }
`;
Enter fullscreen mode Exit fullscreen mode

Step 3: Build the Frontend UI

Edit the App.js file to include ApolloProvider and display items:

import React from 'react';
import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
import ItemList from './components/ItemList';

consi client = new ApolloClient({
  uri: 'http://localhost:4000/graphql',
  cache: new InMemoryCache(),
});

function App() {
  return (
    <ApolloProvider client={client}>
      <div className="App">
        <h1>CRUD Application</h1>
        <ItemList />
      </div>
    </ApolloProvider>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Create the ItemList.js component:

import React from 'react';
import { useQuery } from '@apollo/client';
import { GET_ITEMS } from '../graphql/queries';

function ItemList() {
  const { loading, error, data } = useQuery(GET_ITEMS);

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return (
    <ul>
      {data.items.map(item => (
        <li key={item.id}>{item.name}: {item.description}</li>
      ))}
    </ul>
  );
}

export default ItemList;
Enter fullscreen mode Exit fullscreen mode

Run the frontend:

npm start
Enter fullscreen mode Exit fullscreen mode

Conclusion

Congratulations! You’ve built a basic CRUD application with GraphQL, React, Node.js, and MongoDB. This project lays the foundation for more advanced features, such as authentication, pagination, and complex relationships. Keep experimenting and enhancing your application to master this tech stack!

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay