Decouple Frontend and Backend with Postman Mock Server in Angular

Every developer understands how frustrating it is to call an API and have it fail or return an error. Apart from the frustration, this adds cost to the project.

Postman makes it simple for front-end developers to reduce or eliminate their dependency on the backend and servers. It is called Postman Mock Servers. In your Angular project, you just need to do some simple configuration to do the API call to the mock servers instead of the actual API.

In a nutshell, your front end will make the API call, the interceptor in the Angular project will intercept it, and based on the environment file in use, the call will either go to the mock server or to the actual API.

API

The flow of HTTP calls when using mock servers and interceptors

How can it help us?

Imagine you are a front-end developer working on a feature that requires you to call an API, and its response will provide you with the data to use and display. Every time you call the API, the server is down, or there are some issues with the backend that prevent you from making a successful call. Such a situation will slow you down and can block you.

Using the mock server will eliminate the dependency on the backend during development. Instead of calling the backend, your frontend will call the mock server and URL, which will return the mock response.

It is important to ask for the mock response/JSON from your backend team. Do not try to build one yourself, as you might not know exactly what will be returned. The backend team will have the documents and/or contract about the structure of the response, hence providing an accurate mock to you. Otherwise, you will end up developing based on a wrong response structure. When the actual API is called, and you will get the actual response, your feature might break.

Setting up the Postman mock server

  • After opening Postman, you will find the option on the left sidebar.
    My work
  • If you do not see it, you can easily add it by following these steps.
  • First, click on the ‘configure workspace sidebar’, which is the last option on the left sidebar.
    History
  • Then enable ‘Mock Server’.
    Mock server
  • Click on the ‘Mock server’ option. It will prompt you to create one.
    Workspace
  • When you click on ‘Create mock server’, you will be presented with a screen to create an API URL.
    API url
  • Under ‘Request method’ you can choose whether it is a ‘GET’, ‘POST’, or any other method.
  • Under ‘Request URL’, you need to keep the ‘{{url}}’ part as it is one generated by Postman. We will see later how to call it. After the ‘/’, you can add any string required, based on your naming convention’ to form the url you wish to call/.
  • ‘Response code’ is the one you usually get from backend/API responses. It can be 200, 400 or 500. You can choose which one you require for your development.
  • The response body contains a sample JSON response. The mock URL is called this mock response will be returned.
  • Below is an example.
    Next
  • You can create as many as you require.
  • When you are done, click on ‘Next’.
  • On the next screen, you are prompted to provide some information about the mock server./
    Prompted
  • In the ‘Mock Server Name’, you must provide a name for the mock server you are creating.
  • ‘Environment’ refers to the environment variable you have already created in Postman itself and want to associate with this mock server. More about environment variables here [https://learning.postman.com/docs/sending-requests/variables/variables/]
  • The ‘Simulated a fixed network delay’ allows you to set some delays before getting your response. You can choose the delay from the dropdown.
  • Below is the one I have created.
    Create
  • When completed, click on ‘Create Mock Server’.
  • After some seconds, the mock server is created. The screen below will be displayed.
    Display
  • You will see a URL highlighted in red in the section. This is the generated URL that we have seen in section 3.
  • When you open ‘Collections’ [1] from the left sidebar, you will see a collection [2] has been created for your mock server. When you open it, you will see the following.
    Collections
  • The ‘url’ in ‘3’ is the generated one.
  • When you hover on it, you will see its full form.
    Hover
  • When you click on ‘Send’, you will see that the sample response that you provided during the creation will be returned.
    Send

Setting an Angular project to use the mock server

Create environment files in your angular project. More about this here: https://www.c-sharpcorner.com/article/harnessing-the-power-of-environments-using-angular/

For each environment, create an object for its corresponding base URL. Below is an example.

Angular project

Create an Interceptor: Interceptors are a powerful feature in Angular that helps manage HTTP communication in a clean and maintainable way.

An HttpInterceptor in Angular is a service that implements the HttpInterceptor interface and is used to intercept and handle HTTP requests and responses globally (across the whole project). Interceptors are part of Angular's HttpClient module and provide a way to modify or manipulate HTTP requests before they are sent to the server and responses before they are processed by the application.

Generate an interceptor service using the following.

ng generate service interceptors/mock-server

You will find your newly created service under app > interceptor

Below is the code for the interceptor. Note that I have called my mock-server. service.t.

import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';

@Injectable({
  providedIn: 'root'
})
export class MockServerInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const mockReq = req.clone({
      url: `${environment.baseUrl}${req.url}`
    });
    return next.handle(mockReq);
  }
}

The baseUrl is retrieved from the environment file. The ‘${req.url}’ is dynamic and will be the part after the ‘/’ in the API URL. The rest is boilerplate code.

In the app.module.ts, add the ‘HttpClientModule’ in the imports and the following line in the provider.

[
  { 
    provide: HTTP_INTERCEPTORS, 
    useClass: MockServerInterceptor, 
    multi: true 
  }
]

Once the two previous steps are done, the interceptor part is ready to be used.

You can now implement your API call.

For the sake of this example, I will call a function from the ngOnInit. This function will make the API call. Below is the code

constructor(private http: HttpClient) {}
ngOnInit(): void {
  console.log('loaded');
  this.makeApiCall();
}
makeApiCall(): void {
  this.http.get('/dinosaurs').subscribe({
    next: response => {
      console.log('API response:', response);
    },
    error: error => {
      console.error('API error:', error);
    }
  });
}

First, in the constructor, set the http client. If this is not done, you will get an error every time you use ‘this. HTTP.

The ‘/dinosaurs’ can be considered as the ‘${req. url}’ part from the interceptor.

Since we are using an environment file, the ‘baseUrl’ variable from the different environment files will be used based on the command used to serve the application. More information in this article: https://www.c-sharpcorner.com/article/harnessing-the-power-of-environments-using-angular/

In our example, if we build using ng serve, the environment.development.ts will be used, and hence the mock server will also be used.

Environment

When you check the response, you will see the mock response being returned.

Response

When you are using the ‘ng serve --configuration=production’ command, the environment.ts file will be used. Remember that no change in code is done. You just serve the application with the command required per environment. In this case, the actual API will be called.

Command

The response also will be the one from the actual API call.

API call

Why is the interceptor recommended?

Using an interceptor is recommended over directly calling the environment variable before each HTTP call for several reasons.

1. Centralized Logic

  1. Interceptor: An interceptor allows you to centralize and manage common logic for all HTTP requests in one place. This includes adding headers, handling authentication, logging, error handling, and modifying request URLs.
  2. Direct Call: If you use the environment variable directly in each call, you would need to repeat the same logic in multiple places, leading to code duplication and increased maintenance effort.

2. Separation of Concerns

  1. Interceptor: Keeps your components and services clean and focused on their primary responsibilities. The interceptor handles cross-cutting concerns like modifying URLs or adding headers.
  2. Direct Call: Mixing environment-specific logic with business logic can make your code harder to read and maintain.

3. Ease of Configuration

  1. Interceptor: You can easily switch between different environments (e.g., development, staging, production) by configuring the interceptor without changing the code in multiple places.
  2. Direct Call: You would need to update the environment variable in every HTTP call, which is error-prone and cumbersome.

4. Consistency

  1. Interceptor: Ensures that all HTTP requests are consistently handled in the same way, reducing the risk of missing configurations or headers in some requests.
  2. Direct Call: Increases the risk of inconsistencies if you forget to include the environment variable or headers in some requests.

Conclusion

Dependencies are a major blocker in the development world. Waiting for an issue to be resolved or for an API to work can be time-consuming. However, the front end and back end can easily be decoupled, eliminating the dependencies. In this way, front-end developers are able to work independently and without back-end constraints.

Postman makes it simple to set up mock servers, and Angular Interceptor helps us route API calls correctly.

In this article, we have seen how to do both and what the outcome is.

Resources