Design Patterns — Proxy in Angular

Bulicka Ola
Design Patterns — Proxy in Angular
4 min readJul 5, 2024
Image generated by Copilot AI

Structural patterns describe ways to combine classes and objects into larger structures.

Structural patterns consist of:
1. Adapter
2. Composite
3. Proxy
4. Flyweight
5. Facade
6. Bridge
7. Decorator

The Proxy design pattern (aka intermediary) is useful when creating an object is time-consuming and resource-intensive. It allows postponing the creation of this object until the time when the object is actually needed.

The Proxy design pattern can be used in the following situations:

  1. Performance optimization: when the file takes a long time to load
  2. Remote objects: when an object is located in a different address space (for example on a server) and loading it over the network may take a long time, especially during periods of network congestion. A proxy can act as an intermediary in communication between a client and a remote object
  3. Access control: if we want to restrict access rights to an object, the Proxy design pattern can verify the user’s permissions before forwarding the request to the target object
  4. Resource management: when you want to manage resources such as network connections, files, modules, or functions, the proxy design pattern can monitor and control access to these resources
  5. Network Interface: when you want to provide a network interface to a local object, the proxy design pattern can translate method calls into network messages and vice versa.

If you want to see the full demo, check out my demo project.

The Proxy design pattern can be illustrated in many ways. I will present an example of a converter that maps text to JSON. For this example, you need to additionally install two libraries:

npm install express
npm install cors

Next, create a server.js script in the project’s root directory. Define an HTTP GET route for a path that will return text. Below is the entire implementation of the server script:

const express = require('express');
const cors = require('cors');
const app = express();
const port = 3000;

app.use(cors());

app.get('/text-data', (req, res) => {
res.type('text').send('This is a plain text response.');
});

app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});

Afterwards, you need to start the server with the command:

node server.js

in the directory where the server.js script is located.

The service with a method for fetching data from the server is presented as follows:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

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

private apiUrl = 'http://localhost:3000/text-data';

constructor(private http: HttpClient) {}

getTextData(): Observable<string> {
return this.http.get(this.apiUrl, { responseType: 'text' });
}
}

Here is the entire implementation of the Proxy design pattern:

import { Component } from '@angular/core';
import { DataService } from '../../common/service/data.service';
import { map, take } from 'rxjs';


export abstract class JsonParser {
abstract parse(text: string): any;
}
export interface ConvertStringToObject {
description: string;
}

@Component({
selector: 'app-proxy',
template:`
<h3>The design pattern Proxy is also known as an intermediary.
It serves the function of intermediating between two abstractions.
</h3>
<div>{{ (textData$| async)?.description }}</div>`,
styleUrl: './proxy.component.scss',
providers: [DataService]
})
export class ProxyComponent extends JsonParser {
textData$ = this.dataService.getTextData()
.pipe(
take(1),
map(val => this.parse(val))
);

constructor(private dataService: DataService) { super() }

parse(value: string): ConvertStringToObject {
if (typeof value === 'string') {
return { description: value };
}
return value;
}
}

The core is the abstract class JsonParser that defines the conversion of a string to a ConvertStringToObject object. Of course, the object can be more complex. The ProxyComponent class inherits from JsonParser, which already contains the full implementation of the parse method. In this method, the text is converted to an object of the specified interface.

Summary:

I want to present the ideology of the Proxy design pattern. It acts as an intermediary between one abstraction and another, where one of the abstractions can be a large file, an incorrect data format, user permission verification, or many other things. Its purpose is to perform functions that support user interaction.

Materials:

  1. Java. Wzorce projektowe. Translation: Piotr Badarycz. Original title: Java design patterns. A Tutorial. Author: James William Cooper

--

--