wip: finishing fixing the API routes

This commit is contained in:
Nabil Ould Hamou 2024-12-02 13:49:39 +01:00
parent a2c494dbd2
commit 869762af25
4 changed files with 75 additions and 53 deletions

View file

@ -5,7 +5,7 @@
export let time: string; // Heure du dernier message export let time: string; // Heure du dernier message
</script> </script>
<a href={`/chat/${id}`} class="chat-item p-4 border rounded-md hover:bg-gray-100 cursor-pointer flex justify-between items-center"> <a href={`/chats/${id}`} class="chat-item p-4 border rounded-md hover:bg-gray-100 cursor-pointer flex justify-between items-center">
<div> <div>
<p class="font-semibold text-lg">{title}</p> <p class="font-semibold text-lg">{title}</p>
<p class="text-sm text-gray-500 truncate">{lastMessage}</p> <p class="text-sm text-gray-500 truncate">{lastMessage}</p>

View file

@ -57,15 +57,13 @@ export async function POST({ request }) {
channels.push(canal); channels.push(canal);
logger.debug(`Added channel (${canal.id}) to channels cache.`);
await redisClient.set('channels', JSON.stringify(channels), { EX: 600 }); await redisClient.set('channels', JSON.stringify(channels), { EX: 600 });
console.log('Liste des canaux mise à jour dans Redis');
// 5. Retourner le canal créé dans la réponse
return json(canal, { status: 201 }); return json(canal, { status: 201 });
} catch (err) { } catch (err) {
// Gérer les erreurs et les retourner logger.error(err);
console.error('Erreur lors de la création du canal:', err);
return json({ error: 'Erreur lors de la création du canal' }, { status: 500 }); return json({ error: 'Erreur lors de la création du canal' }, { status: 500 });
} }
} }

View file

@ -1,42 +1,34 @@
import { json } from '@sveltejs/kit'; import { json } from '@sveltejs/kit';
import prisma from '$lib/prismaClient'; import prisma from '$lib/prismaClient';
import redisClient from '$lib/redisClient'; import redisClient from '$lib/redisClient';
import logger from '$lib/logger';
// Récupérer les informations du canal et le dernier message (avec cache Redis) // Récupérer les informations du canal et le dernier message (avec cache Redis)
export async function GET({ params }) { export async function GET({ params }) {
const canalId = parseInt(params.id); const channelId = params.id;
// Clé cache pour les informations du canal et le dernier message const channelCacheKey = `channel:${channelId}:info`;
const canalCacheKey = `canal:${canalId}:info`;
try { try {
// Vérifier si les informations du canal et le dernier message sont dans le cache Redis const cachedChannel = await redisClient.get(channelCacheKey);
const cachedCanalData = await redisClient.get(canalCacheKey); if (cachedChannel) {
if (cachedCanalData) { logger.debug(`Cache entry found, fetching channel (${channelId}) from cache`);
console.log('✅ Cache hit pour les informations du canal et le dernier message'); return json(JSON.parse(cachedChannel));
return json(JSON.parse(cachedCanalData));
} }
console.log('❌ Cache miss'); logger.debug(`No cache entry was found, fetching channel (${channelId}) from database`);
// Si non, récupérer les informations du canal et le dernier message depuis Prisma const canal = await prisma.channel.findUnique({
const canal = await prisma.canal.findUnique({ where: { id: channelId },
where: { id: canalId },
include: {
users: true, // Inclut les utilisateurs associés au canal
},
}); });
if (!canal) { if (!canal) {
logger.debug(`No channel for id ${channelId} was found in database`)
return json({ error: 'Canal non trouvé' }, { status: 404 }); return json({ error: 'Canal non trouvé' }, { status: 404 });
} }
// Récupérer le dernier message
const lastMessage = await prisma.message.findFirst({ const lastMessage = await prisma.message.findFirst({
where: { canalId }, where: { id: channelId },
include: { orderBy: { createdAt: 'desc' },
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 // Créer un objet combiné pour le canal et le dernier message
@ -45,30 +37,51 @@ export async function GET({ params }) {
lastMessage, // Inclure uniquement le dernier message 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, NX: true}); // Cache pendant 5 minutes const cachedChanels = await redisClient.get('channels');
let channels = cachedChanels != null ? JSON.parse(cachedChanels) : [];
channels.push(canal);
channels = channels.sort(
(
a: { messages: { createdAt: Date }[]; createdAt: Date },
b: { messages: { createdAt: Date }[]; createdAt: Date }
) => {
const lastMessageA = a.messages[0]?.createdAt || a.createdAt ? a.createdAt : new Date();
const lastMessageB = b.messages[0]?.createdAt || b.createdAt ? b.createdAt : new Date();
return new Date(lastMessageB).getTime() - new Date(lastMessageA).getTime();
}
);
logger.debug(`Added channel (${canal.id}) to channels cache.`);
await redisClient.set('channels', JSON.stringify(channels), { EX: 600 });
logger.debug(`Creating a new cache entry with key channel:${channelId}:info`);
await redisClient.set(channelCacheKey, JSON.stringify(canalData), {EX: 600, NX: true}); // Cache pendant 5 minutes
console.log('❌ Cache miss - Mise en cache des résultats');
return json(canalData); return json(canalData);
} catch (err) { } catch (err) {
console.error(err);
logger.error(err);
return json({ error: 'Erreur lors de la récupération du canal ou du dernier message' }, { status: 500 }); 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é // Supprimer un canal et invalider le cache associé
export async function DELETE({ params }) { export async function DELETE({ params }) {
const canalId = parseInt(params.id); const channelId = params.id;
try { try {
// Supprimer le canal de la base de données // Supprimer le canal de la base de données
await prisma.canal.delete({ await prisma.channel.delete({
where: { id: canalId }, where: { id: channelId },
}); });
logger.debug(`Deleting channel (${channelId}) from database`);
// Invalider le cache logger.debug(`Deleting channel (${channelId}) from cache`);
await redisClient.del(`canal:${canalId}:info`); await redisClient.del(`channel:${channelId}:info`);
return json({ message: 'Canal supprimé avec succès' }); return json({ message: 'Canal supprimé avec succès' });
} catch (err) { } catch (err) {
@ -79,31 +92,24 @@ export async function DELETE({ params }) {
// Modifier un canal // Modifier un canal
export async function PUT({ params, request }) { export async function PUT({ params, request }) {
const canalId = parseInt(params.id); const channelId = params.id;
const { nom, domaine } = await request.json(); // On suppose que ce sont les champs à mettre à jour const { nom } = await request.json();
// Clé cache pour les informations du canal et le dernier message // Clé cache pour les informations du canal et le dernier message
const canalCacheKey = `canal:${canalId}:info`; const canalCacheKey = `channel:${channelId}:info`;
try { try {
// Mettre à jour les informations du canal dans la base de données // Mettre à jour les informations du canal dans la base de données
const updatedCanal = await prisma.canal.update({ const updatedCanal = await prisma.channel.update({
where: { id: canalId }, where: { id: channelId },
data: { data: {
nom, // Nom du canal name: nom,
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 // Récupérer le dernier message associé au canal après mise à jour
const lastMessage = await prisma.message.findFirst({ const lastMessage = await prisma.message.findFirst({
where: { canalId }, where: { id: channelId },
include: {
user: { select: { id: true, pseudo: true } },
},
orderBy: { createdAt: 'desc' }, orderBy: { createdAt: 'desc' },
}); });
@ -113,8 +119,26 @@ export async function PUT({ params, request }) {
lastMessage, // Inclure uniquement le dernier message lastMessage, // Inclure uniquement le dernier message
}; };
// Mettre en cache les nouvelles informations pendant 5 minutes const cachedChannels = await redisClient.get('channels');
await redisClient.set(canalCacheKey, JSON.stringify(canalData), { EX: 300, NX: true }); let channelsArrays = cachedChannels != null ? JSON.parse(cachedChannels) : [];
channelsArrays = channelsArrays.filter((u: { id: string }) => u.id !== updatedCanal.id);
channelsArrays.push(canalData);
channelsArrays = channelsArrays.sort(
(
a: { messages: { createdAt: Date }[]; createdAt: Date },
b: { messages: { createdAt: Date }[]; createdAt: Date }
) => {
const lastMessageA = a.messages[0]?.createdAt || a.createdAt ? a.createdAt : new Date();
const lastMessageB = b.messages[0]?.createdAt || b.createdAt ? b.createdAt : new Date();
return new Date(lastMessageB).getTime() - new Date(lastMessageA).getTime();
}
);
logger.debug(`Updated channel (${channelId}) in channels cache`);
await redisClient.set('channels', JSON.stringify(channelsArrays), { EX: 600 })
logger.debug(`Updated cache entry with key channel:${channelId}:info`);
await redisClient.set(canalCacheKey, JSON.stringify(canalData), { EX: 600, NX: true });
return json(canalData); return json(canalData);
} catch (err) { } catch (err) {

View file

@ -1,7 +1,7 @@
export async function load({ fetch }) { export async function load({ fetch }) {
try { try {
// Appel API ou récupération de données // Appel API ou récupération de données
const res = await fetch('/api/canals', { const res = await fetch('/api/channels', {
method: 'GET', method: 'GET',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'