Projet · API & Architecture

App
Météo.

Application météo en temps réel avec villes favorites. Le front, statique, ne connaît aucune clé d'API : il interroge une API PHP qui fait proxy vers OpenWeatherMap et persiste les favoris en MySQL, sans aucun système de compte.

HTML CSS JavaScript PHP API REST
Aperçu de l'App Météo
Type Projet personnel
Stack JS · PHP · API REST
Contexte Projet personnel · 2026
APIs OpenWeatherMap

Consommer une API tierce sans exposer sa clé.

Brancher une application front sur une API tierce pose toujours la même question : où vit la clé d'accès ? Appelée directement depuis le navigateur, elle est lisible par n'importe quel visiteur dans l'onglet réseau et donc réutilisable par un tiers, sur le quota du propriétaire du compte.

Ce projet traite le problème par une couche serveur intermédiaire : une petite API PHP détient la clé, interroge OpenWeatherMap, et ne renvoie au front que les champs strictement nécessaires. La même couche persiste les villes favorites en MySQL, rattachées à un identifiant de visiteur anonyme ce qui permet de retrouver ses favoris sans jamais créer de compte ni collecter de donnée personnelle.

Une contrainte de plateforme structure toute l'architecture : le portfolio est déployé sur Vercel, qui n'exécute pas de PHP. Le front et l'API vivent donc sur deux hébergements distincts, ce qui impose de traiter explicitement le partage entre origines (CORS).

8
Champs d'un contrat de données maîtrisé, découplé du format d'OpenWeatherMap
2
Hébergements distincts : front statique et API PHP
0
Donnée personnelle demandée pour conserver ses favoris

Un front statique, une API dédiée.

Quatre briques : la recherche côté client, le proxy PHP qui protège la clé, la persistance MySQL des favoris, et la gestion du déploiement réparti.

→ 01

Recherche de ville.

Le front n'appelle jamais OpenWeatherMap. Il interroge une seule adresse, définie par la constante API_BASE, et bascule automatiquement entre l'API locale et l'API en ligne selon le domaine servi. Les erreurs (ville introuvable, service injoignable, délai dépassé) sont traduites en messages lisibles plutôt qu'en échec silencieux.

→ 02

Proxy PHP et clé protégée.

weather.php lit la clé dans un fichier de configuration exclu du dépôt, appelle OpenWeatherMap en cURL, puis renvoie une réponse normalisée : ville, pays, température, ressenti, humidité, vent, description en français. Le contrat de données est ainsi maîtrisé et indépendant du format du fournisseur.

→ 03

Favoris sans système de compte.

À la première visite, un identifiant anonyme est généré via crypto.randomUUID() et conservé en localStorage. Toutes les opérations sur les favoris sont scopées sur cet identifiant côté MySQL, avec une contrainte d'unicité sur le couple visiteur/ville qui rend les ajouts idempotents. Aucun e-mail, aucun mot de passe.

→ 04

Déploiement réparti et CORS.

Vercel n'exécutant pas de PHP, l'API est hébergée séparément. Les deux origines communiquent via une liste blanche explicite de domaines jamais un joker avec gestion de la requête préliminaire. Les accès en base passent tous par des requêtes préparées PDO.

Cherchez votre ville.

Saisissez une ville pour obtenir sa météo en direct, puis ajoutez vos villes favorites elles vous seront proposées à la prochaine visite.

→ Villes favorites
Aucune ville favorite pour le moment.

Ce que ce projet démontre.

→ 01

Sécurisation d'un secret tiers

Compréhension de la frontière client / serveur : ce qui est envoyé au navigateur est public. La clé reste dans un fichier de configuration exclu du dépôt, jamais dans le code livré.

→ 02

Architecture sous contrainte de plateforme

Identification en amont d'une limite d'hébergement Vercel n'exécute pas de PHP et conception d'une architecture répartie qui en tient compte, plutôt que découverte du problème au déploiement.

→ 03

Modélisation et persistance relationnelle

Conception d'un schéma MySQL avec contrainte d'unicité, CRUD complet scopé par visiteur, et accès exclusivement via requêtes préparées PDO.

→ 04

Personnalisation sans friction

Un identifiant anonyme suffit à offrir une expérience personnalisée : ni inscription, ni mot de passe, ni collecte de donnée personnelle. Le parcours reste ouvert dès la première seconde.

La couche qui protège la clé.

// Proxy OpenWeatherMap la clé ne quitte jamais le serveur (api/weather.php)
$config = require __DIR__ . '/config.php';  // fichier gitignoré

$url = 'https://api.openweathermap.org/data/2.5/weather?' . http_build_query([
    'q' => $city, 'appid' => $config['owm_api_key'], 'units' => 'metric', 'lang' => 'fr',
]);

// Le front ne reçoit qu'un contrat de données maîtrisé, pas la réponse brute
echo json_encode([
    'city' => $data['name'],
    'temp' => round($data['main']['temp']),
    'icon' => $data['weather'][0]['icon'] ?? '01d',
]);

// Favoris toujours scopés sur le visiteur, en requête préparée (api/favorites.php)
$stmt = $pdo->prepare('SELECT city, country FROM favorites WHERE visitor_id = ?');
$stmt->execute([$visitor]);
→ Projet suivant
Ghost Room Detector automatisation Google Calendar.
Voir le projet