Monica v3 arrive avant la fin de 2026. Reconstruite de zéro. Toujours open source. Découvrir ce qui arrive
Monica
Tous les articles
9 min de lecture

Building Monica : nous avons construit le navigateur de base de données que nous voulions pour Laravel

En reconstruisant Monica, nous avons créé un petit navigateur de base de données en lecture seule pour Laravel, et nous avons décidé de le publier comme paquet indépendant.

Regis Freyd Fondateur

Ceci est un nouvel article de la série Building Monica, dans laquelle j'écris sur la reconstruction complète de Monica. La plupart des articles de cette série porteront probablement sur le produit lui-même : les relations, les rappels, la personnalisation, les activités, la vie privée, et toutes les questions qui accompagnent la tentative de représenter la vie des gens dans un logiciel. Mais reconstruire une grande application produit aussi de plus petites choses en chemin. LaraDB en fait partie.

Pendant que je travaillais sur Monica v3, je me suis rendu compte que je passais beaucoup de temps à regarder directement la base de données. Ce n'est pas particulièrement inhabituel quand on construit une application Laravel. On crée un contact et on vérifie ce qui a été écrit. On crée une relation et on inspecte les lignes concernées. On modifie un rappel et on vérifie les dates. On lance une action, on rafraîchit les données, on suit une clé étrangère, et on recommence de nombreuses fois dans la journée.

Il existe déjà beaucoup de bonnes façons de faire cela. Tinker est utile, mais pas simple ni rapide à utiliser. Des applications comme TablePlus, DBeaver, phpMyAdmin ou Adminer peuvent être très utiles, mais pas pour une consultation rapide. J'utilise TablePlus régulièrement, surtout quand j'ai besoin d'écrire des requêtes, de modifier des données ou d'inspecter le schéma en détail. Mais la plupart du temps, en développant Monica, je n'avais pas besoin d'un outil de gestion de base de données. Je voulais seulement un moyen rapide de voir ce qu'il y avait dans la base, sans quitter l'application sur laquelle je travaillais déjà.

C'était l'idée de départ de LaraDB. Installer une dépendance de développement, aller sur /db, et voir la base de données.

composer require --dev monicahq/laradb

Ce que vous obtenez est très simple. Les tables s'affichent à gauche, les lignes à droite, et la page tourne à l'intérieur de l'application Laravel elle-même. LaraDB prend en charge SQLite, MySQL et MariaDB, ainsi que PostgreSQL.

LaraDb affichant la table value_list_items : la liste des 41 tables à gauche, leurs lignes à droite, et les colonnes de clés étrangères rendues sous forme de liens que l'on peut suivre.

Un navigateur plutôt qu'un gestionnaire de base de données

La décision la plus importante que nous avons prise a été de garder LaraDB en lecture seule. Il n'y a pas de bouton de modification, pas de bouton de suppression, pas de formulaire d'insertion ni de console SQL. Les deux routes exposées par le paquet sont des routes GET, et le paquet n'émet que des instructions SELECT.

C'est en partie une décision de sécurité, mais c'est surtout une question de périmètre. Il existe déjà des outils matures pour gérer des bases de données, et reproduire une partie de leurs fonctionnalités à l'intérieur de Laravel ne rendrait pas LaraDB plus utile pour le problème que nous essayions de résoudre.

Le paquet évite également d'accepter des identifiants ou des requêtes arbitraires venant du navigateur. Une table demandée doit d'abord exister dans le schéma découvert par le pilote. Les identifiants sont échappés selon le moteur de base de données. Les valeurs utilisées pour suivre les clés étrangères sont passées en paramètres liés. Il n'y a pas d'interface pour soumettre du SQL arbitraire, parce que le SQL arbitraire ne fait pas partie de la raison d'être du paquet.

Un petit outil peut rester compréhensible s'il a une mission très précise. LaraDB est censé répondre à la question de ce qui se trouve actuellement dans la base de données et de la manière dont ces lignes sont liées entre elles. Il n'est pas censé devenir un remplaçant d'un vrai client de base de données.

Ce dont nous avons fini par avoir besoin

L'interface reflète ce périmètre étroit. LaraDB liste les tables du schéma courant et affiche leurs lignes dans un tableau dense. Les types de colonnes sont indiqués, les clés primaires et étrangères sont identifiées, les valeurs NULL se distinguent visuellement des chaînes vides, et les valeurs longues sont tronquées pour que les grandes colonnes de texte ou de JSON ne rendent pas la page inutilisable.

Les clés étrangères se sont révélées être l'une des fonctionnalités les plus utiles pour Monica. Si une colonne référence une autre table, sa valeur peut être suivie directement. Un clic ouvre la table référencée, filtrée sur la ligne correspondante. C'est particulièrement utile dans Monica v3, parce qu'un nombre croissant de domaines y sont représentés par des relations explicites entre plusieurs tables plutôt que par de gros enregistrements autonomes.

La page expose aussi un peu de contexte sur la base de données et la requête en cours. Selon ce que le moteur de base de données met à disposition, LaraDB peut afficher le moteur et sa version, le nom de la base, sa taille, le nombre d'index et d'autres métadonnées propres au moteur. Pour la page en cours, il montre également l'instruction SQL qui a produit le résultat et le temps qu'a pris la requête.

Il existe aussi une représentation JSON d'une table. C'était peu coûteux à ajouter une fois la couche base de données séparée du rendu HTML, et cela s'est avéré utile pour inspecter des données en dehors de la page elle-même.

Le frontend est volontairement autonome. Le paquet embarque son propre CSS et son propre JavaScript, et ne dépend pas de la chaîne d'assets de l'application hôte. Installer LaraDB ne devrait pas obliger à ajouter une configuration Tailwind, une dépendance Alpine ou une étape de build supplémentaire à un projet existant.

L'abstraction de la base de données est devenue le vrai travail

Afficher des lignes dans un navigateur est simple. Prendre en charge SQLite, MySQL et PostgreSQL de manière cohérente, c'est là que la plus grande partie du travail intéressant a fini par se trouver.

Les moteurs diffèrent nettement dans la façon dont ils exposent le schéma et les métadonnées de la base. Lister les tables, décrire les colonnes, trouver les clés primaires, résoudre les clés étrangères, compter les lignes et récupérer les informations au niveau de la base demandent des requêtes différentes selon le moteur. Même des détails comme l'échappement des identifiants doivent être traités correctement plutôt que comme une opération SQL générique.

LaraDB masque ces différences derrière une petite interface de pilote. La couche Laravel demande des tables, des colonnes, des lignes et des métadonnées sans avoir besoin de savoir si la connexion sous-jacente est SQLite, MySQL ou PostgreSQL.

Une partie simplifiée du contrat ressemble à ceci :

public function listTables(): array;

public function getColumns(string $table): array;

public function getRowCount(
    string $table,
    ?RowFilter $filter = null,
): int;

public function getRows(
    string $table,
    int $page,
    int $perPage,
    ?RowFilter $filter = null,
): TablePage;

public function getForeignKeys(string $table): array;

Chaque pilote de base de données implémente ces opérations différemment, tandis que le reste de LaraDB travaille avec les objets de résultat communs renvoyés par l'interface.

Une conséquence intéressante de cette conception est que le cœur du code de lecture de la base ne dépend pas du tout de Laravel. Il travaille directement avec PDO. Laravel s'occupe de la découverte du paquet, de la configuration, du routage et du rendu, mais l'inspection de la base peut être utilisée séparément.

use LaraDb\DriverFactory;

$pdo = new PDO('sqlite:database.sqlite');
$driver = DriverFactory::fromPdo($pdo);

foreach ($driver->listTables() as $table) {
    echo $table->name;
}

Lecture seule ne veut pas dire inoffensif

Le fait que le paquet soit en lecture seule l'empêche de corrompre la base de données, mais cela ne rend pas anodin le fait d'exposer cette base. Un navigateur de base de données peut révéler chaque ligne de chaque table à toute personne capable de l'atteindre, ce qui est évidemment une préoccupation sérieuse pour une application comme Monica.

Pour cette raison, LaraDB est conçu pour être installé comme dépendance de développement.

composer require --dev monicahq/laradb

Un déploiement de production normal, fait avec composer install --no-dev, ne contiendra pas le paquet. LaraDB est aussi désactivé par défaut en dehors de l'environnement local, et ses routes utilisent par défaut les middlewares web et auth lorsqu'elles sont activées.

Les petites choses qui sortent d'une grande reconstruction

Quand j'ai commencé la série Building Monica, je m'attendais à ce que l'essentiel des textes porte sur les grandes décisions d'architecture et de produit derrière Monica v3. Cela restera le cas. Mais je veux aussi documenter certains des outils et des idées plus modestes qui sortent de cette reconstruction, parce qu'ils font partie du travail eux aussi.

LaraDB n'est pas une pièce majeure de Monica v3, et il ne cherche pas à devenir un produit important en soi. C'est simplement un petit outil de développement qui a supprimé une gêne récurrente pour nous. Le paquet est utile précisément parce que son périmètre est limité, et j'aimerais qu'il le reste.

Si vous travaillez sur des applications Laravel et que vous ouvrez souvent un client de base de données uniquement pour inspecter ce que votre code vient d'écrire, LaraDB pourrait vous être utile également.

composer require --dev monicahq/laradb

Puis allez sur /db.

Le code source est disponible sur github.com/monicahq/laradb.

À lire ensuite

2026-08-30 Nous reconstruisons Monica

Nous reconstruisons Monica de zéro, et cette nouvelle série va documenter comment.