Apprentissage NESTJS Partie 3: Cache de données

Dans cette troisième partie de la série NESTJS Learning, nous allons expliquer comment permettre la mise en cache et l’intégration du cache Azure Redis.
Il s’agit de la troisième partie de la série NESTJS Learning.
Dans cette partie, nous apprendrons la mise en cache. Cette partie de la série couvrira les sujets suivants:
- Activer la mise en cache au niveau de l’application
- Activer la mise en cache au niveau de l’itinéraire
- Cache en mémoire
- Intégration du cache Azure Redis
- Travailler avec des clés
NESTJS propose un cachemodule intégré qui permet une intégration facile des fonctionnalités de mise en cache. La mise en cache peut être appliquée à différents niveaux:
- Niveau d’application
- Niveau du contrôleur
- Niveau d’itinéraire
Il prend en charge divers magasins de mise en cache, notamment:
- Cache en mémoire (par défaut)
- Des magasins externes comme le cache Azure Redis
Par défaut, NESTJS utilise un cache en mémoire. Pour commencer avec la mise en cache, commencez par installer le package Cache Manager dans votre projet NESTJS.
npm install @nestjs/cache-manager cache-manager
Après l’installation, pour utiliser le magasin en mémoire, importez et enregistrez le cachemodule dans Appmodule.
import { CacheModule } from '@nestjs/cache-manager';
Ensuite, importez le cachemodule dans l’appmodule comme indiqué ci-dessous,
@Module({
imports: [
CacheModule.register({
ttl:30000
}),
],
controllers: [AppController, ProductController, BookController],
providers: [AppService, ProductService, BookService],
})
export class AppModule {}
Ici, nous avons réglé la valeur du temps de vivre (TTL) à 30 000 millisecondes (30 secondes). Cela signifie que NESTJS mettra en cache les données pour cette durée avant d’envoyer une nouvelle demande à la base de données.
La mise en cache peut être activée au niveau de l’itinéraire en utilisant le @UseInterceptors()
décorateur et passant CacheInterceptor
comme son argument.
@Get()
@UseInterceptors(CacheInterceptor)
async findAll() {
try {
const books = await this.bookService.findAll();
return books;
} catch (error) {
throw new Error('Error fetching books');
}
}
Maintenant, au lieu d’interroger la base de données à chaque demande, le /book
Endpoint cache les données pour 30 000 millisecondes (30 secondes) et ne fait qu’un nouvel appel de base de données après l’expiration du cache.
Différentes options de configuration
Pour personnaliser le comportement de mise en cache, diverses configurations peuvent être définies pour le CacheModule
. Ils sont les suivants:
ttl
– Il est temps de vivre pour les éléments de cachemax
– Nombre maximum d’articles en cacheisGlobal
– Si c’est vrai, le cache est disponible dans le monde dans l’applicationstore
– le magasin de cache à utiliser; il pourrait être en mémoire ou un magasin externe
Outre les propriétés ci-dessus, d’autres paramètres, tels que le port et le mot de passe, du magasin externe peuvent également être configurés ici.
@Module({
imports: [
CacheModule.register({
ttl:30000,
max: 100,
isGlobal: true,
store: 'memory',
}),
],
controllers: [AppController, BookController],
providers: [AppService, BookService],
})
export class AppModule {}
Si nécessaire, vous pouvez remplacer le paramètre de cache global au niveau de l’itinéraire. Par exemple, pour remplacer la valeur TTL, utilisez le @CacheTTL()
décorateur.
@Get()
@UseInterceptors(CacheInterceptor)
@CacheTTL(60)
async findAll() {
try {
return await this.bookService.findAll();
} catch (error) {
throw new Error('Error fetching books');
}
}
Les deux points importants que vous devez garder à l’esprit sont que:
- Seulement
GET()
Les points d’extrémité sont mis en cache. - Les routes qui injectent l’objet de réponse natif
@Res()
Impossible d’utiliser l’intercepteur de cache.
Comme l’objet de réponse natif @Res()
ne peut pas être utilisé avec la mise en cache et vous suivez la série d’articles NESTJS, assurez-vous de mettre à jour le BookController
depuis Partie 2 Pour éviter d’utiliser @Res
comme indiqué ci-dessous:
import { Body, Controller, Delete, Get, HttpStatus, Param, Post, Put, Res, UseInterceptors } from '@nestjs/common';
import { BookService } from './book.service';
import { Book } from './book.entity';
import { CacheInterceptor, CacheTTL } from '@nestjs/cache-manager';
@Controller('book')
export class BookController {
constructor(private readonly bookService: BookService) {}
@Post()
async create(@Body() bookData: Partial<Book>) {
try {
return await this.bookService.create(bookData);
} catch (error) {
throw new Error('Error creating book');
}
}
@Get()
@UseInterceptors(CacheInterceptor)
@CacheTTL(60)
async findAll() {
try {
return await this.bookService.findAll();
} catch (error) {
throw new Error('Error fetching books');
}
}
@Get(':id')
async findOne(@Param('id') id: string) {
try {
const book = await this.bookService.findOne(Number(id));
if (book) {
return book;
} else {
throw new Error('Book not found');
}
} catch (error) {
throw new Error('Error fetching book');
}
}
@Delete(':id')
async remove(@Param('id') id: string) {
try {
const result = await this.bookService.remove(Number(id));
if (result.affected && result.affected > 0) {
return { message: 'Book deleted' };
} else {
throw new Error('Book not found');
}
} catch (error) {
throw new Error('Error deleting book');
}
}
@Put(':id')
async update(
@Param('id') id: string,
@Body() updateData: Partial<Book>
) {
try {
const updatedBook = await this.bookService.update(Number(id), updateData);
if (updatedBook) {
return updatedBook;
} else {
throw new Error('Book not found');
}
} catch (error) {
throw new Error('Error updating book');
}
}
}
Si vous ne mettez pas à jour le BookController
Pour éviter d’utiliser le @Res
Objet, la mise en cache peut ne pas fonctionner comme prévu.
Intégration du cache Azure pour redis
Pour intégrer Azure Cache pour Redis, configurez le cache Azure pour Redis dans le portail Azure.
Vous devriez avoir le cache redis configuré comme ci-dessous:
Vous aurez besoin des détails suivants:
- Nom d’hôte – Disponible sur le Aperçu Page dans le portail Azure.
- Mot de passe – Trouvé sous Authentification dans le portail Azure. C’est la même chose que le Clé primaire.
Dans l’appmodule, enregistrez le CacheModule
en utilisant le cache Azure nom d’hôte, port et mot de passe Comme indiqué ci-dessous:
CacheModule.register({
store: 'redis',
host: your host name ,
port: 10000,
password: primary key value',
tls: {},
ttl: 50000,
isGlobal: false,
}),
C’est toute la configuration dont vous avez besoin pour utiliser le cache Azure Redis pour la mise en cache de données dans une API NESTJS.
Utilisation de clés personnalisées
Jusqu’à présent, nous avons utilisé des clés par défaut pour la mise en cache. Cependant, l’utilisation de clés personnalisées offre plusieurs avantages.
- Contrôle à grains fins – Il est facile d’accéder à un élément de données spécifique avec le nom de clé.
- Invalidation facile – Chaque fois que les données sous-jacentes changent, il est facile d’invalider les données mises en cache à l’aide du nom de clé.
- Performance – Les clés permettent un accès rapide et direct aux données mises en cache. Étant donné que Redis est optimisé pour les recherches basées sur les clés, il offre des opérations de lecture et d’écriture extrêmement rapides.
- Expiration personnalisée – Vous pouvez définir des valeurs de temps différentes pour vivre (TTL) pour différentes clés.
L’utilisation de clés dans Redis fournit un contrôle précis, efficace et flexible sur les données mises en cache, aidant votre application à s’exécuter plus rapidement et à rester plus facile à gérer.
Voyons comment les clés personnalisées peuvent être utilisées pour la mise en cache. Nous modifierons le FindAll()
Méthode dans le BookService
Pour utiliser une clé personnalisée pour la mise en cache.
Tout d’abord, injectez le CACHE_MANAGER
dans le BookService
Comme indiqué ci-dessous:
constructor(
@Inject(CACHE_MANAGER) private cacheManager: Cache
) { }
N’oubliez pas non plus d’importer CacheManager
et Cache
dans le BookService
.
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
Ensuite, définissez une variable pour la clé personnalisée:
private readonly bookCacheKey = 'my_custom_books_key';
Ensuite, modifiez le findAll()
Méthode pour récupérer les données du cache, et si aucune donnée en cache n’est disponible, lisez les données de la base de données.
async findAll(): Promise<Book[]> {
let books = await this.cacheManager.get<Book[]>(this.bookCacheKey);
if (books) {
return books;
}
books = await this.bookRepository.find();
await this.cacheManager.set(this.bookCacheKey, books, 1000);
return books;
}
Dans le BookController
pour utiliser mis à jour FindAll()
Fonction du service:
- Retirer
@CacheKey()
- Supprimer l’utilisation de
CacheInterceptor
Étant donné que la mise en cache est désormais gérée dans le service, le BookController findAll()
La méthode devient aussi simple que ci-dessous:
@Get()
async findAll() {
try {
return await this.bookService.findAll();
} catch (error) {
throw new Error('Error fetching books');
}
}
De cette façon, vous pouvez utiliser une clé personnalisée pour la mise en cache.
Résumé
La mise en cache est une technique puissante pour améliorer les performances de l’API. Dans cet article, vous avez appris les principes fondamentaux de la mise en œuvre de la mise en cache dans NESTJS, vous équipant de l’intégrer dans vos projets d’API. J’espère que vous l’avez trouvé utile – merci pour la lecture!
Source link