Design Patterns: Chain of Responsibility Pattern in TypeScript

Tram Ho

How to use Chain of Responsibility in TypeScript to solve real world problems in web projects.

Welcome to the Design Patterns in TypeScript series, this series will introduce some useful Design Patterns in web development using TypeScript.

Design Patterns are very important for web developers and we can code better by mastering them. In this article, I will use TypeScript to introduce the Chain of Responsibility .

Design Patterns are very important for web Devs and we can do better coding by mastering them. In this article, I will use TypeScript to introduce the Chain of Responsibility .

Chain of Responsibility

Chain of Responsibility is a way to avoid coupling between the sender and receiver of requests by having multiple request handlers. In Chain of Responsibility, multiple objects are connected by a reference from each object to its next object to form a chain (next,next,next…). Requests are passed along the chain until one of the objects in the chain decides to handle the request.


Different positions in the company have different responsibilities and authorities. Take the example of a company’s leave process, when applying for leave only needs to be approved by the leader, not needing to be transferred to superiors and directors. If a link in the Chain of Responsibility cannot handle the current request, if there is a next link, the request will be forwarded to the next link for processing.

During software development, for Chain of Responsibility , a common application scenario is middleware . Let’s see how to use Chain of Responsibility to handle requests.

To better understand the following code, let’s first take a look at the corresponding UML diagram:


In the image above, we define an Interface Handler . The following two functions are defined in this interface:

  • use(h: Handler): Handler => Used to register handler (middleware)
  • get(url: string, callback: (data: any) => void): void => Register get request handler

Handler interface

Then we define an abstract Class AbstractHandler , encapsulating the handling logic of Chain of Responsibility . That is, combine different handlers to form a reference string.

AbstractHandler abstract class

Based on the abstract Class AbstractHandler , we define AuthMiddleware and LoggerMidddleware respectively. AuthMiddleware middleware is used to handle user authentication and LoggerMidddleware middleware is used to log each request.

AuthMiddleware class

LoggerMiddleware class

With the middleware AuthMiddleware and LoggerMidddleware , define a Route class to register these middleware.

Route class

After defining the Route Route class, we can use it and register the middleware in the following way:


When you successfully run the above code, the corresponding output is shown in the following figure:


Chain of Responsibility usage scenarios:

  • Want to send a request to one of many objects without explicitly specifying the request recipient.
  • There are many objects that can handle a request and which object handles the request is determined automatically at runtime and the Client only needs to send the request to the Chain.


As always, I hope you enjoyed this article and learned something new.

Thank you and see you in the next posts!

If you find this blog interesting, please give me a like and subscribe to support me. Thank you.



Share the news now

Source : Viblo