Flyweight Examples:

Java
Java
C#
C#
Python
Python
TypeScript
TypeScript
▸ Flyweight Quick Review

HTTP Request Caching in TypeScript

If you're wanting to save on time and bandwidth, caching HTTP requests for similar responses is a good way to do so, as long as you have an expiration date on how long you can cache a result for; nobody want's last year's information today!

For simplicity, we won't be making actual HTTP requests, and our system will be designed as a concurrent solution, but there wouldn't need to be a lot done to convert these to ready-to-go solutions!

An HTTP Request Cache is a great example of the Flyweight pattern in action; the request response is relatively expensive and time-consuming to acquire, so storing it away where it can be quickly accessed would save on a lot of resources!

Flyweight Object:

class WebRequestResult
{
   // The time in minutes, converted to milliseconds, to cache the request for
   // This will cache for 1 minute.
   public static readonly CACHE_TIME_MINUTES: number = 1 * 60 * 1000;

   // The data is our flyweight: relatively expensive to compute (wait for request response takes time and bandwidth!)
   public data: string;

   // What time is this data "fresh" until? (Milliseconds)
   private readonly cacheUntilTime: number;

   constructor(data: string)
   {
        this.data = data;
        this.cacheUntilTime = Date.now() + WebRequestResult.CACHE_TIME_MINUTES;
   }

   // Is the result too old / needs to be refreshed?
   public isExpired(): boolean
   {
       return Date.now() > this.cacheUntilTime;
   }
}

WebRequestCache Factory:

class WebRequestCache
{
   // Uses ES6 Map for help:
   private static cache: Map<string, WebRequestResult> = new Map<string, WebRequestResult>();

   /*
       We're going to bend the rules a little and make this concurrent
       as opposed to asynchronous which is what a real-world scenario would be.
   */
   public static getRequest(url: string): WebRequestResult
   {
       let result: WebRequestResult = null;
       
       if(this.cache.has(url))
       {
           result = this.cache.get(url);
       }

       // If the result is not cached or is expired, replace:
       if(result === null || result.isExpired())
       {
           result = new WebRequestResult(`Some cool data from ${url}`);
           // Replace the cached request:
           this.cache.set(url, result);
       }

       return result;
   }
}

Demo:

class FlyweightSolution
{
   public static execute()
   {
       // Create a request:

       let result = WebRequestCache.getRequest("mycoolapi/link/endpoint");

       console.log(result.data); // Some cool data from mycoolapi/link/endpoint

       console.log(result.isExpired()); // false

       // Wait until the result expires and check again:
       setTimeout(() =>
       {
           console.log(result.isExpired()) // true
       }, WebRequestResult.CACHE_TIME_MINUTES);
   }
}

// Run the demo:
FlyweightSolution.execute();

Find any bugs in the code? let us know!