Integration of Angular with Microservices

Background

I’m a lazy backend .net engineer. I know a little bit about .net technologies, but I don’t know much about the frontend java-script framework like Angular. My manager told me to write down some typescript codes so that the front-end can talk to outsiders, like RESTful web API services. If I tell him that I don’t know how to do it, you guys know what would happen. Anyway, let's come back to the main focus. Please note that this is just for beginners who just wanna fire and forget. Don’t blame me. I don’t know much about typescripts.

Solution and Design Plan

  • At the beginning, I separated the whole task into four parts:
  • Reading app-settings configurations.
  • Environmental configuration settings are based on development, QA, or production.
  • Connection establishment with outsider RESTful web API services.
  • Requests with queries or commands to the services.
    RESTful web API

Basic knowledge - I guess you know it. So, in short.

  • Restful web API: it’s an interface for communication with two or more applications.
  • TypeScript: Compared to javaScript, It supports writing code with object-oriented concepts.
  • Singleton design pattern: It creates a single shared instance of the object.
  • Dependency injection design pattern: It is a style of object configuration in which objects are set by an external entity.

Explanation of each of the steps

  • Step 1: Read all the configuration at runtime from the appSettings.json file so that applications can use this data at runtime.
  • Step 2: Check the environment. Is it development, QA, or production? Set the environment settings data that you got from step 1.
  • Step 3: Create a base class for the service to get the API service, for instance. Design it using the concept of the singleton design pattern. Get the settings data from step 2.
  • Step 4: The main service class calls all the get/post/put/patch/delete required requests to the RESTful web API. Add the base class from step 3.
  • Step 5: Use the dependency Injection pattern to inject the dependent service. Inject the dependent service class into the component class. Call the required methods of the service from the component class. Use the class from step 4.

Implementation of each of the classes using typeScript in the Angular project

Install the required packages

  1. appsettings-json-reader package: Read all the data from the JSON file.
    npm install appsettings-json-reader
  2. Axios package: Promise-based API method called.
    npm install axios --save
    

I guess you already know how to implement step1 & step2.

Implementing steps 3

Creating the base class using a command.

ng g class BaseApiClientService

Creating base class

import { Injectable } from "@angular/core";
import axios from "axios";
import { AppSettingsConfig } from "../../configuration/app-settings-config";

@Injectable()
export class BaseApiClientService {
  private appSettings!: AppSettingsConfig;
  private helloApiBaseUrl!: string;

  constructor() {
    // Holding configuration-data object.
    this.appSettings = new AppSettingsConfig();

    // Getting base URL of the Hello-API.
    this.helloApiBaseUrl = this.appSettings.apiEndPoint;
  }

  // Main API Instance.
  readonly HelloApiInstance = () => {
    return axios.create({
      baseURL: this.helloApiBaseUrl,
      timeout: 5000,
      headers: {
        Accept: 'application/json',
        cors: true,
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, PATCH, OPTIONS',
      }
    });
  }
}

Implementing steps 4

Creating the service class using a command.

ng g service Hello-Api-Service

Creating service class

import { Injectable } from '@angular/core';
import { AxiosInstance } from 'axios';
import { ConstApiSubPathConfig } from '../../configuration/const-api-sub-path-config';
import { BaseApiClientService } from './base-api-client-service';

@Injectable({
  providedIn: 'root'
})
export class HelloAPIServiceService {
  readonly helloWebApiInstance: AxiosInstance;

  constructor(private baseClient: BaseApiClientService)
  {
    this.helloWebApiInstance = this.baseClient.HelloApiInstance();
  }

  GetHelloDataList(isActive:boolean) {
    //// It will add the pathSufix with the main base URL path.
    let pathSufix = '/' + ConstApiSubPathConfig.HelloApiSubDaListPathSufix;

    //// Get request:Returns the response.
    return this.helloWebApiInstance.get(pathSufix, {
      params: { IsActive: isActive }});
  }

  AddHelloMessage(helloMessageObj: any) {
    let pathSufix = '/' + ConstApiSubPathConfig.HelloApiSubPathSufix;

    //// Post request:Returns the response.
    return this.helloWebApiInstance.post(pathSufix, helloMessageObj);
  }
}

Implementing Steps 5

Creating the component class using a command.

ng g component HelloServiceGrid --module app

Creating component class

import { Component } from '@angular/core';
import { HelloAPIServiceService } from '../../../core/service/axios-service/hello-api-service.service';

@Component({
  selector: 'app-hello-service-grid',
  templateUrl: './hello-service-grid.component.html',
  styleUrls: ['./hello-service-grid.component.css']
})
export class HelloServiceGridComponent {
  constructor( private api: HelloAPIServiceService){  }
  getHelloDataList()
  {
      let isActive:boolean = true;
      this.api.GetHelloDataList(isActive)
      .then(response => {

        //// if status-code is success.
        if (response.status === 200) {
          /// Response Data from API.
          let result = response.data;

          //// Implement your logic with the data below:
        }
      }).catch(error => console.log('Error message =====> Sorry : ' + error.message));
  }
}

Don’t forget to check the App.module.ts file. Your components should be added to the declarations array, and your services should be added to the providers array.

App Module

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

import { AppComponent } from './app.component';
import { AppSettingsConfig } from './core/configuration/app-settings-config';
import { BaseApiClientService } from './core/service/axios-service/base-api-client-service';
import { HelloAPIServiceService } from './core/service/axios-service/hello-api-service.service';
import { HelloServiceGridComponent } from './pages/HelloService/hello-service-grid/hello-service-grid.component';

@NgModule({
  declarations: [
    AppComponent,
    HelloServiceGridComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [
    AppSettingsConfig,
    BaseApiClientService,
    HelloAPIServiceService
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

In the next part, I’ll describe how to read configurations at runtime and set the environmental configurations to deploy an Angular project to the Azure environment using Azure DevOps CI/CD pipelines. Anyway, gotta go.