How to consume GraphQL CRUD API using React and Apollo

Introduction

In this tutorial we are going to show you how to consume GraphQL CRUD API using React and Apollo. CRUD means Create, Read, Update and Delete operations. Therefore we are going to create client application for GraphQL server. I am going to use Spring Boot framework for implementing GraphQL server.

In the server side implementation we are performing CRUD operations on category and product using GraphQL and Spring Boot. Here in client side implementation using React, I will only show you how to perform CRUD operations of category and performing CRUD operations on product will be similar to the category.

You must install various required modules using command npm install on Windows environment from command line tool.

Related Posts

Prerequisites

Go through the tutorial how to create React project in Windows environment. The name of the project for this tutorial is react-consume-graphql-crud-api.

Make sure you install the following modules to work with GraphQL client.

react-apollo graphql-tag graphql apollo-link-http apollo-client apollo-cache-inmemory

Once your project gets created, next steps are to implement the GraphQL consumption.

GraphQl Spring MySQL CRUD Example

Consume GraphQL CRUD API

The React JS project has been created and it’s time to move on to implementation of the client application.

The file we are going to edit is src/App.js. In this file we will perform CRUD operations on server side code.

In this example we are not going to display any input page for creating new category or updating existing category, but we are going to add new category with hardcoded input and update the existing category with hardcoded input by editing the source code. The idea is to show you how to perform CRUD operations.

The first step is to import the required modules. Next we define Apollo client with required properties link and cache.

For any write operation (create, update, delete) ideally you need to write to cache to get the updated value on UI (User Interface), but I am not going to write to cache. if you want to see the changes on UI, you need to refresh the page.

We have defined GraphQL Query and Mutation for performing read and write operations.

Notice carefully at the below source code how we have used ApolloProvider, Query and Mutation to perform read and write operations.

We perform write operations on button clicks.

import React from 'react';
import gql from 'graphql-tag'
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { Query, Mutation, ApolloProvider } from 'react-apollo'
import { InMemoryCache } from 'apollo-cache-inmemory';

const cache = new InMemoryCache();

const link = new HttpLink({
	uri: 'http://localhost:8080/graphql'
});

const client = new ApolloClient({
	link,
	cache
});

const CATEGORIES_QUERY = gql`
  {
    allCategories {
      id
      name
    }
  }
`

const CATEGORY_CREATE_QUERY = gql`
  mutation addCategory($name: String!) {
    addCategory(name: $name){
	  id,
	  name
	}
  }
`

const CATEGORY_UPDATE_QUERY = gql`
  mutation UpdateCategory($cId:ID!, $name: String!) {
    updateCategory(id: $cId, name: $name){
	  id,
	  name
	}
  }
`

const CATEGORY_DELETE_QUERY = gql`
  mutation DeleteCategory($cId:ID!) {
    deleteCategory(id: $cId)
  }
`

class App extends React.Component {
	constructor(props) {
		super(props);
		this.headers = [
			{ key: 'id', label: 'Id'},
			{ key: 'name', label: 'Name' }
		];
	}
		
	render() {		
		return (
			<ApolloProvider client={client}>
				<Query query={CATEGORIES_QUERY}>
					{
						({ loading, error, data }) => {
							if (loading) return <div>Loading...</div>
							if (error) return <div>Error</div>
			
							const categories = data.allCategories						
			
							return (
								<table>
									<thead>
										<tr>
											{
												this.headers.map(function(h) {
													return (
														<th key = {h.key}>{h.label}</th>
													)
												})
											}
										</tr>
									</thead>
									<tbody>
										{										
											categories.map(function(c, key) {
												return (
													<tr key = {key}>
													  <td>{c.id}</td>
													  <td>{c.name}</td>
													</tr>
												);
											})										
										}
									</tbody>
								</table>
							);
						}
					}
				</Query>
				<Mutation mutation={CATEGORY_CREATE_QUERY}>
					{
						(addCategory, { data, loading, error }) => (
							<div>
								<button onClick={ () => {
									addCategory({ variables: { name: 'Electronics' } });
									}}>
									Add Category
								</button>
								{
									loading &&
									<div>adding category…</div>
								}
								{ 
									data &&
									<div>category added</div>
								}
								{
									error &&
									<div>Error adding category…</div>
								}
							</div>
						)
					}
				</Mutation>
				<Mutation mutation={CATEGORY_UPDATE_QUERY}>
					{
						(updateCategory, { data, loading, error }) => (
							<div>
								<button onClick={ () => {
									updateCategory({ variables: {cId: 28, name: 'Redme' } });
									}}>
									Update Category
								</button>
								{
									loading &&
									<div>updating category…</div>
								}
								{ 
									data &&
									<div>category updated</div>
								}
								{
									error &&
									<div>Error updating category…</div>
								}
							</div>
						)
					}
				</Mutation>
				<Mutation mutation={CATEGORY_DELETE_QUERY}>
					{
						(deleteCategory, { data, loading, error }) => (
							<div>
								<button onClick={ () => {
									deleteCategory({ variables: {cId: 28} });
									}}>
									Delete Category
								</button>
								{
									loading &&
									<div>deleting category…</div>
								}
								{ 
									data &&
									<div>category deleted</div>
								}
								{
									error &&
									<div>Error deleting category…</div>
								}
							</div>
						)
					}
				</Mutation>
			</ApolloProvider>
		);
	}
}

export default App;

Testing the Application

We are done with the coding part. Now let’s test our application how it looks. Make sure you have the server application up and running.

To run client application, i.e., our React application execute npm start on your project’s root directory. Once started it will automatically open the home page on your system’s default browser.

The page will show you with a list of categories on UI (User Interface). We have also put three buttons to add new category, update existing category and delete existing category. Clicking them will do the required job. Make sure you have put appropriate category id in your source code before performing update and delete operations.

consume graphql crud api using react and apollo

When you click on Add Category button to create or add new category, you will see the below screen with message category added.

consume graphql crud api using react and apollo

In the database table you will find new entry.

consume graphql crud api using react and apollo

When you click on Update Category button to update existing category, you will see the below screen with message category updated.

consume graphql crud api using react and apollo

When you click on Delete Category button to delete existing category, you will see the below screen with message category deleted.

consume graphql crud api using react and apollo

Source Code

Download

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *