Skip to content

WebNinjaDeveloper.com

Programming Tutorials




Menu
  • Home
  • Youtube Channel
  • Official Blog
  • Nearby Places Finder
  • Direction Route Finder
  • Distance & Time Calculator
Menu

React.js Apollo Client Project to Build GraphQL CRUD API Server Using Express.js & Mutations in Browser

Posted on October 6, 2022

Welcome folks today in this blog post we will be building a react.js apollo client project where we will be building a graphql crud api server using express.js and mutations. All the full source code of the project is shown below.

 

 

Get Started

 

 

In order to get started you need to make the project folder and then inside that you need to create two folders for frontend and backend as shown below

 

 

mkdir reactapollo

 

cd reactapollo

 

mkdir frontend

 

mkdir backend

 

 

Making the GraphQL Backend API in Express

 

 

Now we will be building the graphql backend api using express and apollo. For this first of all we will be building a node.js project by executing the below commands as shown below

 

 

npm init -y

 

 

This will create the package.json file and after that we will install the dependencies for this project

 

 

npm i express

 

 

npm i cors

 

 

npm i express-graphql

 

 

npm i graphql

 

 

npm i graphql-yoga

 

 

npm i mongoose

 

 

npm i apollo-server-express

 

 

Now Here we have installed the express package to make the web server and also we are installing the mongoose library for storing the data into database. And also we are installing the apollo server package.

 

And also inside your package.json file we need to add the type parameter whose value will be module as shown below

 

 

 

Now make the index.js file and copy paste the following code

 

index.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import express from "express";
import { ApolloServer } from "apollo-server-express";
import cors from "cors";
 
const app = express();
const port = 8080;
 
app.use(express.json()); // body parser
app.use(cors()); //
 
app.listen(port, () => {
  console.log(
    `App is listening on http://localhost:${port}${server.graphqlPath}`
  );
});

 

 

In the very first step we are importing the express library and also including some important middlewares such as cors for avoiding the cors error. And also we are starting the express app at port 8080.

 

 

Connect to MongoDB Database

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import express from "express";
import mongoose from "mongoose";
import cors from "cors";
 
 
const dbName = "library";
const uri = `mongodb://localhost:27017/${dbName}`;
mongoose.Promise = global.Promise;
mongoose.connect(uri, { useNewUrlParser: true });
 
const app = express();
const port = 8080;
 
app.use(express.json()); // body parser
app.use(cors()); //
 
app.listen(port, () => {
  console.log(
    `App is listening on http://localhost:${port}${server.graphqlPath}`
  );
});

 

 

Here we are connecting to Mongodb database using the mongoose library. Here we are providing the database name and also we are providing the mongodb uri where we specify the port number of mongodb which is 27017 followed by db name.

 

 

Including the Apollo Client in Express

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import express from "express";
import mongoose from "mongoose";
import { ApolloServer } from "apollo-server-express";
import cors from "cors";
import { typeDefs } from "./schema.js";
import { resolvers } from "./resolvers.js";
 
const dbName = "library";
const uri = `mongodb://localhost:27017/${dbName}`;
mongoose.Promise = global.Promise;
mongoose.connect(uri, { useNewUrlParser: true });
 
const app = express();
const port = 8080;
const server = new ApolloServer({
  typeDefs,
  resolvers
});
server.applyMiddleware({ app });
 
app.use(express.json()); // body parser
app.use(cors()); // 필수
 
app.listen(port, () => {
  console.log(
    `App is listening on http://localhost:${port}${server.graphqlPath}`
  );
});

 

 

Here as you can see we are applying the apollo client middleware to the express app. At the starting we are including the apollo library. And inside the constructor of Apollo Server we are passing two things which is typedef and resolvers. Now we need to create these two files in the next step.

 

 

Making Schema & Mutations of GraphQL API

 

 

Now we will be making the schema.js file which will contain the schema of the graphql api. This schema will include which data you will be using for the graphql api

 

 

schema.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import { gql } from "apollo-server-express";
 
export const typeDefs = gql`
  type User {
    _id: ID!
    name: String!
    age: Int!
    gender: String!
  }
 
  type Query {
    getUser(_id: ID!): User
    allUser: [User]
  }
 
  input UserInput {
    name: String!
    age: Int!
    gender: String!
  }
 
  type Mutation {
    createUser(input: UserInput): User
    updateUser(_id: ID!, input: UserInput): User
    deleteUser(_id: ID!): User
  }
`;

 

 

Here as you can see we are defining the schema and mutations for the apollo graphql api. And the mutations are createUser for creating a new user, updateUser which will update the exisiting user, deleteUser which will delete the user. We have a User object which will contain the name,age and gender fields.

 

 

Making Resolvers for GraphQL API

 

Now we will be making the resolvers for the schema of graphql api. Here we will defining all the functions which will modify the schema and data.

 

 

resolver.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import User from "./models/user.js";
 
export const resolvers = {
  Query: {
    async getUser(root, { _id }) {
      return await User.findById(_id);
    }, // new
    async allUser() {
      return await User.find();
    }
  },
  Mutation: {
    async createUser(root, { input }) {
      return await User.create(input);
    },
    async updateUser(root, { _id, input }) {
      return await User.findOneAndUpdate({ _id }, input, { new: true });
    },
    async deleteUser(root, { _id }) {
      return await User.findOneAndDelete({ _id });
    }
  }
};

 

 

As you can see we have defined all the four CRUD Methods which will actually create,delete,Update and read all the records from the mongodb database using mongoose. These mutations are very much helpful in graphql apollo api. And also we are importing the Models of mongodb database. So now we need to make a new model folder and inside it we need to make a User.js file and copy paste the following code

 

 

models/User.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// ./models/User.js
import mongoose from 'mongoose';
 
const Schema = mongoose.Schema;
 
const UserSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    age: {
        type: Number
    },
    gender: {
        type: String
    }
});
 
export default mongoose.model('user', UserSchema);

 

 

So in this block of code we are importing the mongoose library. And also we are defining the schema of mongodb database. Also we are defining the datatypes of each field. Lastly we are exporting the model and the schema.

 

 

Now if you open the localhost:8080/graphql we will see the following interface to create mutations and also request some data from the graphql api.

 

 

 

 

As you can see we have a fully fledged graphql apollo server running on port 8080 and here we can perform any filtering and mutations of graphql api.

 

 

Making the React.js Frontend to Consume GraphQL API

 

 

Now we need to create a brand new react.js project inside the frontend folder to consume this graphql api and build a crud frontend. The commands are shown as follows

 

 

npx create-react-app apollographql

 

cd apollographql

 

 

Now we will be installing the dependencies which are required for this react.js project

 

 

npm i apollo-boost

 

 

npm i graphql

 

 

npm i graphql-tag

 

 

npm i react-apollo

 

 

As you can see we are installing the apollo client package for react.js and also graphql packages as well for making http requests to graphql backend api using apollo client.

 

 

Initializing Apollo Client in React.js

 

 

First of all modify the index.js file of your react.js project and including the below code to initialize the Apollo Client in React.js

 

 

index.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import { ApolloProvider } from 'react-apollo';
import ApolloClient from 'apollo-boost';
 
const client = new ApolloClient({
    uri: 'http://localhost:8080/graphql'
})
 
ReactDOM.render(
    <ApolloProvider client={client}>
        <App />
    </ApolloProvider>
, document.getElementById('root'));

 

 

Now inside the App.js file you need to copy paste the below code.

 

 

App.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React from "react";
import ReadUser from "./components/ReadUser";
import CreateUser from "./components/CreateUser";
import UpdateUser from "./components/UpdateUser";
import DeleteUser from "./components/DeleteUser";
 
const App = () => (
  <div>
    <CreateUser />
    <UpdateUser />
    <DeleteUser />
    <h2>GraphQL + MongoDB CRUD</h2>
    <ReadUser />
  </div>
);
 
export default App;

 

 

Here we are including the four components required for the crud operations using the graphl api. So now we need to create this components in the next step.

 

Now guys you need to create a brand new components folder and inside it create the files.First of all we will be reading all the records from the database in ReadUser.js and the code is shown below

 

 

components/ReadUser.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import React from "react";
import { Query } from "react-apollo";
import gql from "graphql-tag";
 
export const ALL_USER = gql`
  query {
    allUser {
      _id
      name
      age
      gender
    }
  }
`;
 
const ReadUser = () => (
  <Query query={ALL_USER}>
    {({ loading, error, data }) => {
      if (loading) return <p>Loading...</p>;
      if (error) return <p>error</p>;
 
      return data.allUser.map(({ _id, name, age, gender }) => (
        <div
          key={_id}
          onClick={e => {
            e.preventDefault();
            window.location.pathname = _id;
          }}
        >
          id: {_id} / name: {name} / age: {age} / gender: {gender}
        </div>
      ));
    }}
  </Query>
);
 
export default ReadUser;

 

 

Here we are defining the actual mutation of readUser which basically uses the map operator to loop through all the records present inside database and showing it on browser. Here we are calling the Query for mutations inside graphql apollo client to make this request.And lastly we are printing out all the details of a certain user in browser. So now if you open the react.js project at port 3000 you will see all the users details printed

 

 

 

 

 

Now we need to create the new component which is called as createUser.js which is actually to insert a new record inside mongodb database and we will be using the mutation createUser as shown below

 

 

components/CreateUser.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import React, { Component } from "react";
import { Mutation } from "react-apollo";
import { ALL_USER } from "./ReadUser";
import gql from "graphql-tag";
 
const CREATE_USER = gql`
  mutation createUser($name: String!, $age: Int!, $gender: String!) {
    createUser(input: { name: $name, age: $age, gender: $gender }) {
      _id
      name
      age
      gender
    }
  }
`;
 
export class CreateUser extends Component {
  constructor(props) {
    super(props);
    this.state = {
      name: "",
      age: 0,
      gender: ""
    };
  }
  render() {
    return (
      <Mutation
        mutation={CREATE_USER}
        update={(cache, { data }) => {
          // 캐시 업데이트를 해서 글 목록이 바로 보이게 하기
          const { allUser } = cache.readQuery({ query: ALL_USER });
          cache.writeQuery({
            query: ALL_USER,
            data: { allUser: allUser.concat([data.createUser]) }
          });
        }}
      >
        {(createUser, { data, loading, error }) => {
          if (loading) return <p>loading...</p>;
          if (error) return <p>error...</p>;
 
          return (
            <div>
              <form
                onSubmit={async e => {
                  e.preventDefault();
                  const { name, age, gender } = this.state;
                  await createUser({
                    variables: { name, age, gender }
                  });
                  this.setState({ name: "", age: 0, gender: "" });
                }}
              >
                <h1> CreateUser </h1>
                <input
                  onChange={e => this.setState({ name: e.target.value })}
                  placeholder="name"
                  type="text"
                  value={this.state.name}
                />
                <input
                  onChange={e =>
                    this.setState({ age: parseInt(e.target.value) })
                  }
                  placeholder="age"
                  type="number"
                  value={this.state.age}
                />
                <input
                  onChange={e => this.setState({ gender: e.target.value })}
                  placeholder="gender"
                  type="text"
                  value={this.state.gender}
                />
                <input
                  disabled={
                    !this.state.name || !this.state.age || !this.state.gender
                  }
                  type="submit"
                  value="Create"
                />
              </form>
            </div>
          );
        }}
      </Mutation>
    );
  }
}
 
export default CreateUser;

 

 

Here guys we have the simple form to create a new User and insert that data inside mongodb database. After the form submit button is clicked it is calling a createUser mutation to actually interact with the backend where mongoose is directly interacting with the mongodb database to store the actual record. If you open the app you will see this actual form

 

 

 

 

 

As you can see we have three fields name,age and gender and a create button which is disabled by default.

 

 

And Now we will create the updateUser.js Component to actually update the existing user as shown below

 

 

components/UpdateUser.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import React, { Component } from "react";
import gql from "graphql-tag";
import { Mutation } from "react-apollo";
 
const UPDATE_USER = gql`
  mutation updateUser($_id: ID!, $name: String!, $age: Int!, $gender: String!) {
    updateUser(_id: $_id, input: { name: $name, age: $age, gender: $gender }) {
      _id
      name
      age
      gender
    }
  }
`;
 
class UpdateUser extends Component {
  constructor(props) {
    super(props);
    this.state = {
      _id: "",
      name: "",
      age: 0,
      gender: ""
    };
  }
 
  componentDidMount() {
    const id = window.location.pathname.split("/")[1];
    this.setState({ _id: id });
  }
 
  render() {
    return (
      <Mutation mutation={UPDATE_USER}>
        {(updateUser, { data, loading, error }) => {
          if (loading) return <p>loading...</p>;
          if (error) return <p>error...</p>;
 
          return (
            <div>
              <form
                onSubmit={async e => {
                  e.preventDefault();
                  const { _id, name, age, gender } = this.state;
                  await updateUser({
                    variables: { _id, name, age, gender }
                  });
                  this.setState({ _id: "", name: "", age: 0, gender: "" });
                  window.location.pathname = "/";
                }}
              >
                <h1> UpdateUser </h1>
                <h3>_id : {this.state._id}</h3>
                <input
                  onChange={e => this.setState({ name: e.target.value })}
                  placeholder="name"
                  type="text"
                  value={this.state.name}
                />
                <input
                  onChange={e =>
                    this.setState({ age: parseInt(e.target.value) })
                  }
                  placeholder="age"
                  type="number"
                  value={this.state.age}
                />
                <input
                  onChange={e => this.setState({ gender: e.target.value })}
                  placeholder="gender"
                  type="text"
                  value={this.state.gender}
                />
                <input
                  type="submit"
                  disabled={
                    !this.state.name || !this.state.age || !this.state.gender
                  }
                  value="Update"
                />
              </form>
            </div>
          );
        }}
      </Mutation>
    );
  }
}
 
export default UpdateUser;

 

 

Now as you can see we have another form this time it is for updating an existing record which is already present inside mongodb database. Here we are using the updateUser mutation when the form submits. This updateUser mutation takes all the fields values name,age and gender and based upon the changes updates the record. The update form looks like this as shown below

 

 

 

 

As you can see we are updating the records by using it’s unique id which is auto generated in mongodb database.

 

 

Now we will be making deleteUser component which actually deletes a record using unique id which is again generated by mongodb database. The deleteUser mutation is really simple here we will simply delete the record and no complex operations involved.

 

 

components/DeleteUser.js

 

 

JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import React, { Component } from "react";
import { Mutation } from "react-apollo";
import gql from "graphql-tag";
 
const DELETE_USER = gql`
  mutation deleteUser($_id: ID!) {
    deleteUser(_id: $_id) {
      _id
      name
      age
      gender
    }
  }
`;
 
class DeleteUser extends Component {
  constructor(props) {
    super(props);
    this.state = {
      _id: ""
    };
  }
 
  componentDidMount() {
    const id = window.location.pathname.split("/")[1];
    this.setState({ _id: id });
  }
  render() {
    return (
      <Mutation mutation={DELETE_USER}>
        {(deleteUser, { loading, error, data }) => {
          if (loading) return <p>Loading...</p>;
          if (error) return <p>error...</p>;
 
          return (
            <div>
              <h1>DeleteUser</h1>
              _id: {this.state._id}
              <button
                onClick={async e => {
                  e.preventDefault();
                  const { _id } = this.state;
                  await deleteUser({
                    variables: { _id }
                  });
                  window.location.pathname = "/";
                }}
              >
                Delete User
              </button>
            </div>
          );
        }}
      </Mutation>
    );
  }
}
 
export default DeleteUser;

 

 

As you can see guys here we have a simple button of delete with every record. If we click that button then that record will be deleted from the mongodb database. And we are deleting it using deleteUser mutation which takes the id of the record to be deleted. The delete User form looks like this

 

 

 

 

This wraps up the application guys. Hopefully you like the project. Thanks for taking the time and reading this post. Please share this post if you like it and bookmark this website for future programming and web development tutorials

 

Recent Posts

  • Javascript PDFObject Library Example to Render PDF Document From URL or From Local PC in Browser
  • Node.js Express Project to Extract Text From Word (.DOCX) File & Save it as Text File in Browser
  • Node.js Tutorial to Parse & Extract Text & Tables From PDF Document Using pdfreader Library in Javascript
  • Node.js Express Project to Stream Local MP4 Video in Webpage Using Fetch API in Javascript
  • Node.js Express Tutorial to Read & Write Stream of Data From Buffer to Server Using Pipes in Browser
  • Angular
  • Bunjs
  • C#
  • Deno
  • django
  • Electronjs
  • java
  • javascript
  • Koajs
  • kotlin
  • Laravel
  • meteorjs
  • Nestjs
  • Nextjs
  • Nodejs
  • PHP
  • Python
  • React
  • ReactNative
  • Svelte
  • Tutorials
  • Vuejs




©2023 WebNinjaDeveloper.com | Design: Newspaperly WordPress Theme