How to consume GraphQL CRUD API using Angular 9 and Apollo

Here we are going to see how to consume GraphQL CRUD API using Angular and Apollo. So this is a client for GraphQL Server API. We are going to use various modules for working with GraphQl client. For GraphQL server side implementation you can use any technology and here I am going to use Spring Boot framework for performing CRUD operations on GraphQL server. CRUD means Create, Read, Update and Delete operations.

In the server side implementation we are performing CRUD operations on category and product using GraphQL and Spring Boot. Here in client side implementation 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 modules using command npm install on Windows environment from command line tool.

Related Posts

Prerequisites

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

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

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

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

GraphQl Spring MySQL CRUD Example

I am using routing in this project, so I need to configure routing module. If you are not using routing then you don’t need to configure.

Routing Module

The routing module decides which component to render on UI (User Interface) based on the HTTP request path.

The following code is written into file src/app/app-routing.module.ts.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { AppComponent } from './app.component';

const routes: Routes = [
	{path: '', redirectTo: 'app', pathMatch: 'full'},
	{path: 'app', component: AppComponent}
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

App Module

To run our Angular application for GraphQL we need to configure required modules.

The following code is written into file src/app/app.module.ts.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { ApolloModule, APOLLO_OPTIONS } from 'apollo-angular';

import {HttpClientModule} from '@angular/common/http';
import {AppRoutingModule} from './app-routing.module';
import {HttpLinkModule} from 'apollo-angular-link-http';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
	ApolloModule,
    BrowserModule,
	HttpLinkModule,
	HttpClientModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

CRUD Operations

Now it is very important to understand how to consume GraphQL for performing CRUD operations on server side. The code is written into src/app/app.component.ts file.

Look at the below source code, we have imported the required modules.

Next we declare a const for querying all categories. This is to inform you that either we can declare the query or mutation in a separate variable and perform the execution or we can directly write the query or mutation and perform the execution.

Next we define the type of the response we are expecting from server side. Here we define type Category. If you define in a separate TypeScript file then you need to put export before type Category and import the TypeScript file.

Next we declare variables for holding data from server side on each operation.

In constructor we create the HttpLink and we use in-memory cache. These two are required properties. The link property is the endpoint of the server side GraphQL implementation and cache is used to put your query data into cache memory.

Finally we define various functions for consuming GraphQL performing CRUD operations.

import { Component, OnInit } from '@angular/core';

import { Apollo, QueryRef } from 'apollo-angular';
import { HttpLink } from 'apollo-angular-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import gql from 'graphql-tag';

const CATEGORIES_QUERY = gql`
	query {
		allCategories{
			id,
			name
		}
	}
`;

type Category = {
  id?: number;
  name?: string;
}

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{

	categories: Category[] = [];
	category: Category;
	createdCategory: Category;
	updatedCategory: Category;

	private query: QueryRef<Category>;

	constructor(private apollo: Apollo, httpLink: HttpLink) {
		apollo.create({
		  link: httpLink.create({ uri: 'http://localhost:8080/graphql' }),
		  cache: new InMemoryCache()
		})
	}
	
	ngOnInit() {
		/*this.apollo.query({
		  query: CATEGORIES_QUERY
		}).subscribe(res => {console.log(res.data['allCategories']); this.categories = res.data['allCategories'];});*/
		//this.getCategories();
		//this.getCategory(1);
		//this.createCategory('test');
		//this.updateCategory(16, 'test hi');
		//this.deleteCategory(14);
	}

	public getCategories = () => {
		this.apollo.query({
		  query: gql`query getCategories{
		  allCategories{
			id,
			name
		  }
		}`
		}).subscribe(result => {
			this.categories = result.data['allCategories'];
			console.log('categories: ' + this.categories);
		});
	}

	public getCategory = (id) => {
		this.apollo.query({
		  query: gql`query getCategory($cId: ID!){
		  category(id: $cId){
			id,
			name
		  }
		}`,
		  variables: { cId: id }
		}).subscribe(result => {
		  this.category = result.data['category'];
		  console.log('category: ' + this.category.id + ' -> ' + this.category.name);
		});
	}

	public createCategory = (name: string) => {
		this.apollo.mutate({
		  mutation: gql`mutation($name: String!){
			addCategory(name: $name){
			  id,
			  name
			}
		  }`,
		  variables: {name: name}
		}).subscribe(result => {
		  this.createdCategory = result.data['addCategory'];
		  console.log('New Category: ' + this.createdCategory.id + ' -> ' + this.createdCategory.name);
		})
	}

	public updateCategory = (id: number, name: string) => {
		this.apollo.mutate({
		  mutation: gql`mutation($cId: ID!, $name: String!){
			updateCategory(id: $cId, name: $name){
			  id,
			  name
			}
		  }`,
		  variables: {cId: id, name: name}
		}).subscribe(result => {
		  this.updatedCategory = result.data['updateCategory'];
		  console.log('Updated Category: ' + this.updatedCategory.id + ' -> ' + this.updatedCategory.name);
		})
	}

	public deleteCategory = (id: number) => {
		this.apollo.mutate({
		  mutation: gql`mutation($cId: ID!){
			deleteCategory(id: $cId)
		   }`,
		  variables: { cId: id}
		}).subscribe(res => {
			console.log(res.data['deleteCategory']);
		})
	}
	
}

UI Component

The file src/app/app.component.html is used to display the data on UI.

In this example I am only displaying a list of categories for rest of the operations you may implement the UI code. But in this example I am calling all the functions from onNgInit(), so you will see the data returned from server side on browser console.

We conditionally render the UI, if at least one category found from server then we display otherwise we display test No category found in red color.

<div *ngIf="categories && categories.length > 0; else elseBlock">
	<h3>Categories</h3>
	<table>
	  <tr>
		<th>ID</th>
		<th>Name</th>
	  </tr>
	  <tr *ngFor="let c of categories">
		<td>{{c.id}}</td>
		<td>{{c.name}}</td>
	  </tr>
	</table>
</div>
<ng-template #elseBlock><div style="color: red;">No category found</div></ng-template>

Testing the Application

Make sure your server application is running before you start your Angular application by executing command ng server --open on project’s root directory.

So once your application is up and running you will see similar to the below page. In console you see list of objects for getCategories() function.

consume graphql crud api using angular and apollo

When you call getCategory(1) function for a category having id 1 then you will below output:

consume graphql crud api using angular and apollo

Let’s say we want to create a new category called Electronics, so we will call function createCategory('Electronics').

consume graphql crud api using angular and apollo

You can check also in the database for the new category entry.

Let’s say we want to update category Electronics to Redme, the we call function updateCategory(19, 'Redme'):

consume graphql crud api using angular and apollo

We can also delete a particular category by calling function deleteCategory(19):

consume graphql crud api using angular and apollo

Source Code

Download

Thanks for reading.

Leave a Reply

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