Ajouts des models et de l'api avec gestion du cache
This commit is contained in:
parent
267dcdf5ea
commit
431c77f970
8 changed files with 472 additions and 0 deletions
|
@ -36,6 +36,9 @@
|
|||
"vite": "^5.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/client": "^5.22.0",
|
||||
"prisma": "^5.22.0",
|
||||
"redis": "^4.7.0",
|
||||
"svelte-radix": "^2.0.1"
|
||||
}
|
||||
}
|
||||
|
|
4
src/lib/prismaClient.ts
Normal file
4
src/lib/prismaClient.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { PrismaClient } from '@prisma/client';
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
export default prisma;
|
11
src/lib/redisClient.ts
Normal file
11
src/lib/redisClient.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import redis from 'redis';
|
||||
|
||||
const client = redis.createClient({
|
||||
url: process.env.REDIS_URL || 'redis://localhost:6379',
|
||||
});
|
||||
|
||||
client.on('error', (err) => console.error('Redis Error:', err));
|
||||
|
||||
await client.connect();
|
||||
|
||||
export default client;
|
123
src/routes/api/canal/[id]/+server.js.ts
Normal file
123
src/routes/api/canal/[id]/+server.js.ts
Normal file
|
@ -0,0 +1,123 @@
|
|||
import { json } from '@sveltejs/kit';
|
||||
import prisma from '$lib/prismaClient';
|
||||
import redisClient from '$lib/redisClient'; // Assurez-vous d'importer le client Redis
|
||||
|
||||
// Récupérer les informations du canal et le dernier message (avec cache Redis)
|
||||
export async function GET({ params }) {
|
||||
const canalId = parseInt(params.id);
|
||||
|
||||
// Clé cache pour les informations du canal et le dernier message
|
||||
const canalCacheKey = `canal:${canalId}:info`;
|
||||
|
||||
try {
|
||||
// Vérifier si les informations du canal et le dernier message sont dans le cache Redis
|
||||
const cachedCanalData = await redisClient.get(canalCacheKey);
|
||||
if (cachedCanalData) {
|
||||
console.log('✅ Cache hit pour les informations du canal et le dernier message');
|
||||
return json(JSON.parse(cachedCanalData));
|
||||
}
|
||||
|
||||
console.log('❌ Cache miss');
|
||||
// Si non, récupérer les informations du canal et le dernier message depuis Prisma
|
||||
const canal = await prisma.canal.findUnique({
|
||||
where: { id: canalId },
|
||||
include: {
|
||||
users: true, // Inclut les utilisateurs associés au canal
|
||||
},
|
||||
});
|
||||
|
||||
if (!canal) {
|
||||
return json({ error: 'Canal non trouvé' }, { status: 404 });
|
||||
}
|
||||
|
||||
// Récupérer le dernier message
|
||||
const lastMessage = await prisma.message.findFirst({
|
||||
where: { canalId },
|
||||
include: {
|
||||
user: { select: { id: true, pseudo: true } },
|
||||
},
|
||||
orderBy: { createdAt: 'desc' }, // Trie par date décroissante, donc le dernier message est récupéré en premier
|
||||
});
|
||||
|
||||
// Créer un objet combiné pour le canal et le dernier message
|
||||
const canalData = {
|
||||
canal,
|
||||
lastMessage, // Inclure uniquement le dernier message
|
||||
};
|
||||
|
||||
// Mettre en cache les informations du canal et le dernier message pendant 5 minutes
|
||||
await redisClient.set(canalCacheKey, JSON.stringify(canalData), 'EX', 300); // Cache pendant 5 minutes
|
||||
|
||||
console.log('❌ Cache miss - Mise en cache des résultats');
|
||||
return json(canalData);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur lors de la récupération du canal ou du dernier message' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// Supprimer un canal et invalider le cache associé
|
||||
export async function DELETE({ params }) {
|
||||
const canalId = parseInt(params.id);
|
||||
|
||||
try {
|
||||
// Supprimer le canal de la base de données
|
||||
await prisma.canal.delete({
|
||||
where: { id: canalId },
|
||||
});
|
||||
|
||||
// Invalider le cache
|
||||
await redisClient.del(`canal:${canalId}:info`);
|
||||
|
||||
return json({ message: 'Canal supprimé avec succès' });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur lors de la suppression du canal' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// Modifier un canal
|
||||
export async function PUT({ params, request }) {
|
||||
const canalId = parseInt(params.id);
|
||||
const { nom, domaine } = await request.json(); // On suppose que ce sont les champs à mettre à jour
|
||||
|
||||
// Clé cache pour les informations du canal et le dernier message
|
||||
const canalCacheKey = `canal:${canalId}:info`;
|
||||
|
||||
try {
|
||||
// Mettre à jour les informations du canal dans la base de données
|
||||
const updatedCanal = await prisma.canal.update({
|
||||
where: { id: canalId },
|
||||
data: {
|
||||
nom, // Nom du canal
|
||||
domaine, // Domaine du canal
|
||||
},
|
||||
include: {
|
||||
users: true, // Inclut les utilisateurs associés au canal
|
||||
},
|
||||
});
|
||||
|
||||
// Récupérer le dernier message associé au canal après mise à jour
|
||||
const lastMessage = await prisma.message.findFirst({
|
||||
where: { canalId },
|
||||
include: {
|
||||
user: { select: { id: true, pseudo: true } },
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
});
|
||||
|
||||
// Créer un objet combiné pour les nouvelles informations du canal et le dernier message
|
||||
const canalData = {
|
||||
canal: updatedCanal,
|
||||
lastMessage, // Inclure uniquement le dernier message
|
||||
};
|
||||
|
||||
// Mettre en cache les nouvelles informations pendant 5 minutes
|
||||
await redisClient.set(canalCacheKey, JSON.stringify(canalData), 'EX', 60 * 5); // Cache pendant 5 minutes
|
||||
|
||||
return json(canalData);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur lors de la mise à jour du canal' }, { status: 500 });
|
||||
}
|
||||
}
|
149
src/routes/api/canal/[id]/messages/+server.ts
Normal file
149
src/routes/api/canal/[id]/messages/+server.ts
Normal file
|
@ -0,0 +1,149 @@
|
|||
import { json } from '@sveltejs/kit';
|
||||
import prisma from '$lib/prismaClient';
|
||||
import redisClient from '$lib/redisClient'; // Assure-toi d'importer ton client Redis
|
||||
|
||||
export async function GET({ params, url }) {
|
||||
const canalId = parseInt(params.id);
|
||||
|
||||
// Gestion de la pagination avec des paramètres optionnels `page` et `limit`
|
||||
const page = parseInt(url.searchParams.get('page')) || 1;
|
||||
const limit = parseInt(url.searchParams.get('limit')) || 10;
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
// Générer une clé cache Redis unique en fonction du canal et des paramètres de pagination
|
||||
const cacheKey = `canal:${canalId}:messages:page:${page}:limit:${limit}`;
|
||||
|
||||
try {
|
||||
// 1. Vérifier si les messages sont déjà dans le cache Redis
|
||||
const cachedMessages = await redisClient.get(cacheKey);
|
||||
if (cachedMessages) {
|
||||
console.log('✅ Cache hit');
|
||||
return json(JSON.parse(cachedMessages)); // Si les données sont en cache, les retourner
|
||||
}
|
||||
|
||||
// 2. Si les messages ne sont pas en cache, récupérer depuis la base de données
|
||||
const messages = await prisma.message.findMany({
|
||||
where: { canalId },
|
||||
include: {
|
||||
user: {
|
||||
select: { id: true, pseudo: true }, // Inclut uniquement l’ID et le pseudo de l’utilisateur
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'asc', // Trie par date croissante
|
||||
},
|
||||
skip: offset,
|
||||
take: limit,
|
||||
});
|
||||
|
||||
// 3. Compter le nombre total de messages pour la pagination
|
||||
const totalMessages = await prisma.message.count({
|
||||
where: { canalId },
|
||||
});
|
||||
|
||||
const response = {
|
||||
messages,
|
||||
pagination: {
|
||||
page,
|
||||
limit,
|
||||
totalMessages,
|
||||
totalPages: Math.ceil(totalMessages / limit),
|
||||
},
|
||||
};
|
||||
|
||||
// 4. Mettre en cache les messages avec une expiration (par exemple 5 minutes)
|
||||
await redisClient.set(cacheKey, JSON.stringify(response), 'EX', 60 * 5); // Cache pendant 5 minutes
|
||||
|
||||
console.log('❌ Cache miss - Mise en cache des résultats');
|
||||
return json(response); // Retourner les données récupérées
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur lors de la récupération des messages' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST({ params, request }) {
|
||||
const canalId = parseInt(params.id);
|
||||
const { userId, text } = await request.json();
|
||||
|
||||
try {
|
||||
// Créer un nouveau message dans la base de données
|
||||
const newMessage = await prisma.message.create({
|
||||
data: {
|
||||
userId,
|
||||
canalId,
|
||||
text,
|
||||
},
|
||||
include: { user: { select: { id: true, pseudo: true } } },
|
||||
});
|
||||
|
||||
updateCaches(); // Mettre à jour les caches après la création d’un nouveau message
|
||||
|
||||
return json(newMessage, { status: 201 });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur lors de la création du message' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function DELETE({ params }) {
|
||||
const messageId = parseInt(params.id);
|
||||
|
||||
try {
|
||||
// Supprimer le message de la base de données
|
||||
await prisma.message.delete({
|
||||
where: { id: messageId },
|
||||
});
|
||||
|
||||
updateCaches(); // Mettre à jour les caches après la suppression d’un message
|
||||
|
||||
return json({ message: 'Message supprimé avec succès' });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur lors de la suppression du message' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// Fonction pour mettre à jour tous les caches des messages
|
||||
function updateCaches(canalId) {
|
||||
// Mettre à jour tous les caches
|
||||
// Mettre à jour toutes les pages dans le cache
|
||||
let page : number = 1;
|
||||
let limit : number = 10;
|
||||
let offset : number = (page - 1) * limit;
|
||||
while (true) {
|
||||
const cacheKey = `canal:${canalId}:messages:page:${page}:limit:${limit}`;
|
||||
const cachedMessages = await redisClient.get(cacheKey);
|
||||
if (!cachedMessages) {
|
||||
break;
|
||||
}
|
||||
const totalMessages = await prisma.message.count({
|
||||
where: { canalId },
|
||||
});
|
||||
const messages = await prisma.message.findMany({
|
||||
where: { canalId },
|
||||
include: {
|
||||
user: {
|
||||
select: { id: true, pseudo: true },
|
||||
},
|
||||
},
|
||||
orderBy: {
|
||||
createdAt: 'asc',
|
||||
},
|
||||
skip: offset,
|
||||
take: limit,
|
||||
});
|
||||
const response = {
|
||||
messages,
|
||||
pagination: {
|
||||
page,
|
||||
limit,
|
||||
totalMessages,
|
||||
totalPages: Math.ceil(totalMessages / limit),
|
||||
},
|
||||
};
|
||||
await redisClient.set(cacheKey, JSON.stringify(response), 'EX', 60 * 5);
|
||||
page++;
|
||||
offset = (page - 1) * limit;
|
||||
}
|
||||
}
|
47
src/routes/api/canals/+server.ts
Normal file
47
src/routes/api/canals/+server.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
import { json } from '@sveltejs/kit';
|
||||
import prisma from '$lib/prismaClient';
|
||||
import redisClient from '$lib/redisClient';
|
||||
|
||||
// GET: Liste tous les canaux
|
||||
export async function GET() {
|
||||
try {
|
||||
const cachedCanaux = await redisClient.get('canaux');
|
||||
if (cachedCanaux) {
|
||||
console.log('✅ Cache hit');
|
||||
return json(JSON.parse(cachedCanaux));
|
||||
}
|
||||
|
||||
console.log('❌ Cache miss');
|
||||
const canaux = await prisma.canal.findMany({
|
||||
include: { users: true, messages: true }, // Inclut les relations
|
||||
});
|
||||
|
||||
await redisClient.set('canaux', JSON.stringify(canaux), { EX: 600 }); // Met en cache
|
||||
return json(canaux);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur serveur' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST({ request }) {
|
||||
const { nom, domaine, userIds } = await request.json();
|
||||
|
||||
try {
|
||||
const canal = await prisma.canal.create({
|
||||
data: {
|
||||
nom,
|
||||
domaine,
|
||||
users: {
|
||||
connect: userIds.map((id) => ({ id })), // Associe des utilisateurs au canal
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return json(canal, { status: 201 });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur lors de la création du canal' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
108
src/routes/api/user/[id]/+server.ts
Normal file
108
src/routes/api/user/[id]/+server.ts
Normal file
|
@ -0,0 +1,108 @@
|
|||
import { json } from '@sveltejs/kit';
|
||||
import redisClient from '$lib/redisClient';
|
||||
import prisma from '$lib/prismaClient';
|
||||
|
||||
export async function GET({ params }) {
|
||||
const userId = params.id;
|
||||
|
||||
try {
|
||||
// Vérifier si l'utilisateur est dans le cache Redis
|
||||
const cachedUser = await redisClient.get(`user:${userId}`);
|
||||
if (cachedUser) {
|
||||
console.log('✅ Cache hit');
|
||||
return json(JSON.parse(cachedUser));
|
||||
}
|
||||
|
||||
console.log('❌ Cache miss');
|
||||
// Si non, récupérer depuis MongoDB via Prisma
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: parseInt(userId) },
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return json({ error: 'Utilisateur non trouvé' }, { status: 404 });
|
||||
}
|
||||
|
||||
// Mettre l'utilisateur en cache
|
||||
await redisClient.set(`user:${userId}`, JSON.stringify(user), { EX: 3600 });
|
||||
|
||||
return json(user);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur serveur' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
export async function POST({ request }) {
|
||||
const { pseudo, nom, prenom, email, password } = await request.json();
|
||||
|
||||
try {
|
||||
const user = await prisma.user.create({
|
||||
data: {
|
||||
pseudo,
|
||||
nom,
|
||||
prenom,
|
||||
email,
|
||||
password,
|
||||
},
|
||||
});
|
||||
|
||||
// Mettre le nouvel utilisateur dans le cache
|
||||
await redisClient.set(`user:${user.id}`, JSON.stringify(user), { EX: 3600 });
|
||||
|
||||
return json(user, { status: 201 });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur lors de la création de l’utilisateur' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// Mettre à jour un utilisateur avec PUT
|
||||
export async function PUT({ params, request }) {
|
||||
const userId = parseInt(params.id);
|
||||
const { pseudo, nom, prenom, email, password } = await request.json(); // Assurez-vous d'envoyer tous les champs nécessaires dans le body
|
||||
|
||||
try {
|
||||
// Mettre à jour l'utilisateur dans la base de données
|
||||
const updatedUser = await prisma.user.update({
|
||||
where: { id: userId },
|
||||
data: {
|
||||
pseudo,
|
||||
nom,
|
||||
prenom,
|
||||
email,
|
||||
password, // Attention à ne pas oublier de sécuriser le mot de passe avec bcrypt ou une autre méthode
|
||||
},
|
||||
});
|
||||
|
||||
// Mettre à jour l'utilisateur dans le cache Redis
|
||||
await redisClient.set(`user:${userId}`, JSON.stringify(updatedUser), 'EX', 3600); // Cache pendant 1 heure (3600 secondes)
|
||||
|
||||
return json(updatedUser);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur lors de la mise à jour de l’utilisateur' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function DELETE({ params }) {
|
||||
const userId = parseInt(params.id);
|
||||
|
||||
try {
|
||||
await prisma.user.delete({
|
||||
where: { id: userId },
|
||||
});
|
||||
|
||||
// Supprimer l'utilisateur du cache Redis
|
||||
await redisClient.del(`user:${userId}`);
|
||||
|
||||
return json({ message: 'Utilisateur supprimé avec succès' });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur lors de la suppression de l’utilisateur' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
27
src/routes/api/users/+server.ts
Normal file
27
src/routes/api/users/+server.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
// src/routes/api/users/+server.js
|
||||
import { json } from '@sveltejs/kit';
|
||||
import redisClient from '$lib/redisClient';
|
||||
import prisma from '$lib/prismaClient';
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
// Vérifier si les utilisateurs sont dans le cache Redis
|
||||
const cachedUsers = await redisClient.get('users');
|
||||
if (cachedUsers) {
|
||||
console.log('✅ Cache hit');
|
||||
return json(JSON.parse(cachedUsers));
|
||||
}
|
||||
|
||||
console.log('❌ Cache miss');
|
||||
// Sinon, récupérer les utilisateurs depuis MongoDB
|
||||
const users = await prisma.user.findMany();
|
||||
|
||||
// Mettre les utilisateurs en cache
|
||||
await redisClient.set('users', JSON.stringify(users), { EX: 600 });
|
||||
|
||||
return json(users);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return json({ error: 'Erreur serveur' }, { status: 500 });
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue