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.
This Angular post is compatible with Angular 4 upto latest versions, Angular 7, Angular 8, Angular 9, Angular 10, Angular 11, Angular 12 and Angular 13
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.json
in it.
$ cd server
$ type NUL > data.json
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
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
$ 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 🙂