Ionic/ Angular Create Mock server using json-server and faker to test HTTP APIs

Today, in this post we will discuss How to create a mock server using json-server and faker library package which acts like a real server and can help to test client-server communication without any need for a real server.

In a real-world application which serves dynamic content in the application is connected to a server having a database. A client-side application like Angular or React communicate to databases through RESTFull APIs. In response to these HTTP calls from Javascript-based application, the server picks up requested data and return back to the application in the JSON format.

During the development phase of the application, we may need a test server which can simulate a real server to test real-world scenarios. But developing a real server with a database requires time and effort to build.

Let’s get started and check how to build a mock server with a database which can be easily handled in a simple JSON file.

#Create an Angular Project

In Angular or Ionic application we make server communication using HTTP calls, is enabled by using HttpClientModule. Here we will create a new Angular application using Angular CLI tool and import HttpClientModule to make HTTP calls to our REST API server.

Make sure you have installed NodeJS and Angular CLI on your system. Install Angular CLI tool by running following NPM command in terminal:

$ npm install -g @angular/cli

Now create a new Angular project by running the following command:

$ ng new angular-fake-server-tutorial

? Would you like to add Angular routing? No
? Which stylesheet format would you like to use? CSS

Move to the working directory with the project

$ cd angular-fake-server-tutorial

 

#Import HttpClientModule

Next, we'll import the HttpClientModule in the App Module file to use HTTP services across the application. Open the app.module.ts file then make the following changes:

// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

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

import { HttpClientModule } from '@angular/common/http'

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

 

#Setup Mock JSON API Server

For our Mock server, we will install json-server to run data.json file as a database and also install faker package to fill the data.json file with random employees records.

Install json-server

Now we will set up for our localhost based server. Go to the terminal window and install the json-server package

$ npm install -g json-server

Then create a new server directory at the project root

$ md server

with a new JSON file data.jsonin it.

$ cd  server
$ type NUL > data.json

Ionic/ Angular Create Mock  server using json-server and faker to test HTTP APIs

In the server > data.json file, add employees JSON object as shown below:

{
    "employees": []
}

The data.json file will act as a database for our mock server.

Install faker

Next, we need to fill the employees object with some random user data. For that, we will use another very popular package known as Faker. This service provides fake data using which we can fill our employees object with a number of random items.

Move back to project root from the server folder

$ cd..

Then Install faker in the project folder using below npm command

$ npm install faker

To fill the employees object with faker data, create filldata.js file in the server folder and place below code in it

$ cd server
$ type NUL > filldata.js
// server > filldata.js
const faker = require('faker');

const database = {
  employees: []
};

for (let i = 1; i <= 150; i++) {
  database.employees.push({
    id: i,
    name: faker.name.findName(),
    jobtype: faker.name.jobTitle(),
    email: faker.internet.email(),
    address: faker.address.streetAddress(),
    imageUrl: faker.image.avatar()
  });
}

console.log(JSON.stringify(database));

Above file will generate random employee data using faker methods. We are running the for loop for 150 times. You can find more available faker methods in the documentation here.

#Creating helper scripts

In the package.json file, we will add two more scripts in the scripts property to generate employees data and run the mock server using json-server.

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "filldata": "node ./server/filldata.js > ./server/data.json",
    "server": "json-server --watch ./server/data.json"
  },

To generate new employees data in the data.json file, run the following command at project root:

$ cd..
$ npm run filldata

Run the mock server by executing below npm command:

$ npm run server

Ionic/ Angular Create Mock  server using json-server and faker to test HTTP APIs

This command will start the database server at this API URL http://localhost:3000/employees

Now you can access this JSON API URL to perform HTTP operation using the below methods:

GET /employees
GET /employees/1
POST /employees
PUT /employees/1
PATCH /employees/1
DELETE /employees/1

Where 1 is the id of employee which can be any id you want to perform operation on.

You can check this article for HTTP operations using a service.

#Create a service to make HTTP calls

As we have a running server with a database filled with employees data, we can perform CRUD (Create, Read, Update & Delete) operations on them.

Let's create a new service file t0 make HTTP calls using HttpClient service provided by Angular's common package.

Run following generate command to create new HttpDataService in the services folder:

In the Visual Studio Code terminal, you can open the new terminal by clicking on the + icon

Ionic/ Angular Create Mock  server using json-server and faker to test HTTP APIs

$ ng generate service services/http-data

Also, create an Interface class for Employee data by running following command defining the type of values for student item.

$ ng generate class models/Employee

then replace the following content in the newly created file "~/models/employee.ts"

export class Employee {
    id: number;
    name: string;
    jobtype: string;
    email: string;
    address: string;
    imageUrl: string;
}

Now update the services/http-data.service.ts file with below code:

// http-data.servie.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Employee } from '../models/employee';
import { Observable, throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class HttpDataService {


  // API path
  base_path = 'http://localhost:3000/employees';

  constructor(private http: HttpClient) { }

  // Http Options
  httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json'
    })
  }

  // Handle API errors
  handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    // return an observable with a user-facing error message
    return throwError(
      'Something bad happened; please try again later.');
  };


  // Create a new item
  createItem(item): Observable<Employee> {
    return this.http
      .post<Employee>(this.base_path, JSON.stringify(item), this.httpOptions)
      .pipe(
        retry(2),
        catchError(this.handleError)
      )
  }

  // Get single Employee data by ID
  getItem(id): Observable<Employee> {
    return this.http
      .get<Employee>(this.base_path + '/' + id)
      .pipe(
        retry(2),
        catchError(this.handleError)
      )
  }

  // Get Employees data
  getList(): Observable<Employee> {
    return this.http
      .get<Employee>(this.base_path)
      .pipe(
        retry(2),
        catchError(this.handleError)
      )
  }

  // Update item by id
  updateItem(id, item): Observable<Employee> {
    return this.http
      .put<Employee>(this.base_path + '/' + id, JSON.stringify(item), this.httpOptions)
      .pipe(
        retry(2),
        catchError(this.handleError)
      )
  }

  // Delete item by id
  deleteItem(id) {
    return this.http
      .delete<Employee>(this.base_path + '/' + id, this.httpOptions)
      .pipe(
        retry(2),
        catchError(this.handleError)
      )
  }
}

In the above service, we have a method to add, update, delete or get single and list of employees. To handle errors we have used RxJs methods and operators.

With this setup, you can easily go ahead with development, there are other services also which are provided by the json-server to sort, orderBy, add pagination, filter the data. Just have a look at the documentation here.

Thanks for ready! have a great day 🙂

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments