Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve performance using output catching #1051

Open
lcnvdl opened this issue Mar 5, 2022 · 1 comment
Open

Improve performance using output catching #1051

lcnvdl opened this issue Mar 5, 2022 · 1 comment

Comments

@lcnvdl
Copy link
Contributor

lcnvdl commented Mar 5, 2022

Hi FoalTS team, I hope you are doing well!

I was looking for a server-side cache implementation in FoalTS but I couldn't find it. I bring you the following feature request:

You can dramatically improve the performance of your web applications by taking advantage of output caching. The output cache enables you to cache the content returned by a controller action. That way, the same content does not need to be generated each and every time the same controller action is invoked.

Imagine, for example, that your application displays a list of database records in a view named Index. Normally, each and every time that a user invokes the controller action that returns the Index view, the set of database records must be retrieved from the database by executing a database query.

If, on the other hand, you take advantage of the output cache then you can avoid executing a database query every time any user invokes the same controller action. The view can be retrieved from the cache instead of being regenerated from the controller action. Caching enables you to avoid performing redundant work on the server.

Source:
Improving Performance with Output Catching - MSDN Article

Usage (example, in foal.ts):

import { Context, Delete, dependency, Get, HttpResponseOK, OutputCache } from '@foal/core';
import { Project } from '../services/project.service';
import { System } from '../services/system.service';

export class ApiController {
  @dependency
  private projects: Project;
  @dependency
  private system: System;

  @OutputCache({ duration: 15 }) // 15 minutes
  @Get('/status')
  async getSystemInformation(ctx: Context) {
    const result = await this.system.doSomeHeavyTask();

    return new HttpResponseOK(result);
  }

  @OutputCache({ varyByParam: 'projectId' }) // Default duration (5 minutes?) - Cache key: projectId (param)
  @Get('/project/:projectId')
  async getResources(ctx: Context) {
    const resources = await this.projects.getResources(ctx.request.params.projectId);

    return new HttpResponseOK(resources);
  }
}
@lcnvdl
Copy link
Contributor Author

lcnvdl commented Apr 22, 2024

I have made a Cache hook a long time ago for my microservices gateway (Foal v2). If you want, you can close this thread (or use this code if is useful):

import { Hook, HookDecorator, HttpResponseOK } from '@foal/core';
import { MemoryCache } from '../services';

export function Cache(): HookDecorator {
  return Hook(async (ctx, services) => {
    if (ctx.request) {
      if (ctx.request.method.toLowerCase() === 'get') {
        const cache = services.get(MemoryCache);

        const key = `req.${ctx.request.url}${ctx.user ? ('+usr=' + ctx.user.id) : ''}`;

        ctx.state.cacheKey = key;

        if (cache.containsKey(key)) {
          const response = cache.getSync(key).value;
          return new HttpResponseOK(response);
        }
      }
    }
  });
}

Usage:

  @Get('/stats/projects')
  @Cache()
  async getAllProjectsStats(ctx: Context) {
    // ...
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Backlog
Development

No branches or pull requests

1 participant