Colas Mérand
24/01/2025
React
MySQL
Neon
5 minutes
Dans le monde du développement web moderne, il est fréquent de travailler sur des projets où le front-end est déjà développé et nécessite une connexion robuste à une base de données. Cette approche modulaire permet une spécialisation des équipes et une meilleure gestion des ressources. Aujourd'hui, nous explorons comment connecter efficacement une application React existante à une base de données MySQL ou Neon, tout en implémentant un système de suivi des modifications utilisateur.
Lorsqu'un front-end React est déjà développé, l'intégration avec une base de données présente plusieurs défis spécifiques :
Chez Platane, nous avons relevé ces défis à de nombreuses reprises pour des clients aux besoins variés, en développant des solutions sur mesure qui allient performance et fiabilité.
Le choix entre MySQL, une base de données relationnelle traditionnelle, et Neon, une solution PostgreSQL serverless plus récente, dépend de plusieurs facteurs :
MySQL reste une solution solide pour de nombreux projets, particulièrement adaptée lorsque :
Neon, basé sur PostgreSQL, offre des avantages significatifs pour certains projets :
Lors du développement de la plateforme Astory, nous avons opté pour PostgreSQL (technologie sur laquelle Neon est basé) pour sa robustesse et sa capacité à gérer efficacement les relations complexes entre les œuvres d'art, les artistes et les locations.
Pour connecter efficacement un front-end React à une base de données, nous recommandons généralement une architecture en couches :
Cette approche modulaire facilite la maintenance et l'évolution du système.
// Exemple simplifié d'architecture pour une API REST avec Express
const express = require('express');
const userService = require('./services/userService');
const authMiddleware = require('./middleware/auth');
const app = express();
app.use(express.json());
// Route protégée avec middleware d'authentification
app.get('/api/data', authMiddleware, async (req, res) => {
try {
const data = await userService.getData(req.user.id);
res.json(data);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
Le suivi des modifications est crucial pour la traçabilité et la conformité dans de nombreuses applications professionnelles. Voici comment nous l'implémentons généralement :
CREATE TABLE user_actions (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
action_type ENUM('CREATE', 'UPDATE', 'DELETE') NOT NULL,
entity_type VARCHAR(50) NOT NULL,
entity_id INT NOT NULL,
changes JSON,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
// Middleware pour capturer les modifications
const auditMiddleware = async (req, res, next) => {
const originalSend = res.send;
res.send = function(data) {
// Enregistrer l'action si la requête a réussi
if (res.statusCode >= 200 && res.statusCode < 300) {
logUserAction({
userId: req.user.id,
actionType: determineActionType(req.method),
entityType: req.path.split('/')[2], // Exemple: /api/users -> users
entityId: req.params.id,
changes: req.body
});
}
originalSend.call(this, data);
};
next();
};
// Hook personnalisé pour les opérations avec audit
function useAuditedMutation(mutationFn) {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
const execute = async (data) => {
setIsLoading(true);
try {
const result = await mutationFn(data);
// L'audit est géré côté serveur
setIsLoading(false);
return result;
} catch (err) {
setError(err);
setIsLoading(false);
throw err;
}
};
return { execute, isLoading, error };
}
Pour le projet Easop, nous avons développé un système d'audit avancé qui a joué un rôle crucial dans la conformité réglementaire de la plateforme de gestion des stock-options, contribuant significativement à sa valorisation lors de l'acquisition par Remote.
La performance est souvent un enjeu majeur lors de l'intégration d'un back-end à un front-end existant. Voici quelques techniques que nous appliquons régulièrement :
// Configuration de Redis pour le cache
const redis = require('redis');
const client = redis.createClient();
async function getCachedData(key, fetchFunction, ttl = 3600) {
const cachedData = await client.get(key);
if (cachedData) {
return JSON.parse(cachedData);
}
const freshData = await fetchFunction();
await client.set(key, JSON.stringify(freshData), 'EX', ttl);
return freshData;
}
// Service avec pagination optimisée
async function getPagedResults(page, pageSize, filters) {
const offset = (page - 1) * pageSize;
// Construction dynamique de la requête avec uniquement les champs nécessaires
const query = buildOptimizedQuery(filters, pageSize, offset);
const [results, totalCount] = await Promise.all([
db.query(query.sql, query.params),
db.query(query.countSql, query.countParams)
]);
return {
data: results,
pagination: {
page,
pageSize,
totalPages: Math.ceil(totalCount / pageSize),
totalCount
}
};
}
Pour le site du Festival Ouaille Note, nous avons implémenté un système de chargement sélectif qui a permis d'atteindre des temps de chargement exceptionnels, contribuant significativement à l'expérience utilisateur et au référencement du site.
La sécurité est primordiale lors de la connexion d'un front-end à une base de données. Voici les mesures essentielles à mettre en place :
// Configuration JWT sécurisée
const jwt = require('jsonwebtoken');
function generateTokens(userId) {
const accessToken = jwt.sign(
{ userId },
process.env.JWT_SECRET,
{ expiresIn: '15m' }
);
const refreshToken = jwt.sign(
{ userId },
process.env.JWT_REFRESH_SECRET,
{ expiresIn: '7d' }
);
return { accessToken, refreshToken };
}
// Utilisation de requêtes paramétrées
async function getUserData(userId) {
// Sécurisé contre les injections SQL
const query = 'SELECT * FROM users WHERE id = ?';
return db.query(query, [userId]);
// À éviter absolument
// const query = `SELECT * FROM users WHERE id = ${userId}`;
// return db.query(query);
}
// Validation avec Joi
const Joi = require('joi');
const userSchema = Joi.object({
username: Joi.string().alphanum().min(3).max(30).required(),
email: Joi.string().email().required(),
password: Joi.string().pattern(new RegExp('^[a-zA-Z0-9]{8,30}$')).required()
});
function validateUser(userData) {
return userSchema.validate(userData);
}
Pour le projet Dealt, nous avons implémenté un système de sécurité multicouche qui a permis de protéger efficacement les données sensibles des utilisateurs de la marketplace, un aspect crucial pour une plateforme de mise en relation.
Lorsque nous avons développé la plateforme de location d'œuvres d'art Astory, nous avons fait face à un défi similaire : connecter un front-end NextJS existant à une base de données PostgreSQL tout en assurant un suivi précis des transactions.
Notre approche a consisté à :
Le résultat ? Une plateforme robuste qui génère aujourd'hui plus de 800 000€ de revenus annuels, avec des temps de chargement exceptionnels et une expérience utilisateur fluide.
La connexion d'un front-end React à une base de données MySQL ou Neon va bien au-delà d'une simple implémentation technique. Elle nécessite une réflexion approfondie sur l'architecture, la performance, la sécurité et la maintenance à long terme.
Chez Platane, nous combinons expertise technique et vision stratégique pour développer des solutions sur mesure qui répondent précisément aux besoins de nos clients, en intégrant les technologies les plus adaptées, qu'il s'agisse de bases de données traditionnelles ou de solutions cloud innovantes.
Vous avez un projet similaire ou souhaitez discuter de vos besoins spécifiques en matière d'intégration de bases de données ? N'hésitez pas à nous contacter via notre formulaire de contact pour échanger avec nos experts. Notre équipe se fera un plaisir d'analyser votre projet et de vous proposer une approche personnalisée qui allie performance, sécurité et évolutivité.
En collaborant avec Platane, vous bénéficiez non seulement de notre expertise technique, mais aussi de notre approche centrée sur vos objectifs business, pour des solutions qui créent une réelle valeur ajoutée.
Vous préférez discuter de vive voix ? Nous aussi et c'est évidemment sans engagement !
Une question, un besoin de renseignements ? N'hésitez pas à nous contacter.