Skip to content

Runtime

La validation runtime confirme si les décisions de domaine et d'API se comportent comme attendu sous une utilisation réelle de requêtes. C'est la couche où ton modèle passe de la conception à l'exécution — et où tu détectes les problèmes avant tes consommateurs.

Objectif du runtime

Le runtime répond à des questions pratiques tôt dans ton processus de développement :

  • Les structures de champs sont-elles prévisibles et cohérentes ?
  • Les résolutions de relations sont-elles cohérentes et correctement imbriquées ?
  • Les hypothèses de pagination et de tri tiennent-elles avec des données réelles ?
  • Les expressions de filtre correspondent-elles au sous-ensemble correct d'enregistrements ?
  • Les valeurs null sont-elles traitées comme tes consommateurs l'attendent ?

En validant ces comportements pendant la modélisation — pas après l'implémentation — tu élimines toute une catégorie d'erreurs d'intégration.

Screenshot rt-01-query-playgroundScreenshot rt-01-query-playground
rt-01-query-playgroundMissing

Panneau de requête runtime pour tests de comportement en direct.

Comment fonctionne le mock runtime

Le moteur de mock runtime est le cœur de Mockomat. Il accepte des requêtes GraphQL et les traduit en opérations MongoDB via une pipeline en quatre étapes :

1. GraphQL Request Parser

La chaîne de requête entrante est analysée en un arbre syntaxique abstrait (AST). Cette étape valide la syntaxe de la requête et extrait les champs demandés, les arguments et les sélections imbriquées.

2. Query Planner

L'AST est analysé conjointement avec les métadonnées de ton modèle (définitions d'entités, flags d'attributs, configurations de relations) pour créer un plan d'exécution. Le planner détermine :

  • Quelles collections MongoDB interroger
  • Quels champs projeter
  • Quelles opérations de filtrage et de tri appliquer
  • Quelles relations doivent être résolues

3. MongoDB Query Builder

Le plan d'exécution est traduit en pipeline d'agrégation MongoDB. Comme MongoDB stocke les données dans des collections plates (dénormalisées), le query builder simule les structures relationnelles :

  • Étapes de lookup — assemblent les données liées entre collections
  • Étapes de match — appliquent les expressions de filtre
  • Étapes de sort — ordonnent les résultats selon les champs demandés
  • Étapes de skip et limit — gèrent la pagination

4. Result Assembler

Les résultats bruts de MongoDB sont restructurés pour correspondre à la structure de réponse GraphQL attendue. Les relations imbriquées sont assemblées dans la hiérarchie parent-enfant correcte, et les noms de champs sont associés à leurs équivalents GraphQL.

Cette pipeline s'exécute à chaque requête. Ce que tu vois en prévisualisation est exactement ce que les consommateurs externes recevront du même endpoint.

Screenshot rt-01b-runtime-pipelineScreenshot rt-01b-runtime-pipeline
rt-01b-runtime-pipelineMissing

Pipeline runtime en quatre étapes : Parse → Plan → Build → Assemble.

Exemples de requêtes

Toutes les requêtes utilisent le même endpoint :

text
POST /mock/{slug}/graphql

Requête de liste

Récupérer une collection paginée d'enregistrements :

graphql
query {
  products(offset: 0, limit: 20) {
    id
    name
    price
    category {
      id
      name
    }
  }
}

Requête de détail

Récupérer un seul enregistrement par son identifiant :

graphql
query {
  product(id: "abc-123") {
    id
    name
    price
    description
    category {
      id
      name
    }
  }
}

Requête avec filtrage

Appliquer des expressions de filtre pour affiner les résultats :

graphql
query {
  products(
    filter: {
      filterGroup: {
        operator: AND
        items: [
          { attribute: "price", operator: GE, value: "10" }
          { attribute: "price", operator: LE, value: "50" }
        ]
      }
    }
    limit: 10
  ) {
    id
    name
    price
  }
}

Requête avec tri

Ordonner les résultats par un champ triable :

graphql
query {
  products(
    sort: { field: "price", direction: DESC }
    limit: 10
  ) {
    id
    name
    price
  }
}

Requête avec relations imbriquées

Traverser les relations pour inclure les données liées :

graphql
query {
  customers(limit: 5) {
    id
    firstName
    lastName
    orders {
      id
      totalAmount
      createdAt
      items {
        id
        productName
        quantity
      }
    }
  }
}

Filtrage en détail

Le système de filtrage supporte des expressions typées et combinables qui peuvent être combinées avec une logique booléenne.

Opérateurs disponibles

OpérateurDescriptionFonctionne avec
EQÉgalTous les types
NENon égalTous les types
LTInférieur àNombres, dates
GTSupérieur àNombres, dates
LEInférieur ou égalNombres, dates
GESupérieur ou égalNombres, dates
LIKEContient une sous-chaîneChaînes
IS_NULLLe champ est nullTous les types
IS_NOT_NULLLe champ n'est pas nullTous les types

Combiner les filtres

Les filtres utilisent l'algèbre booléenne avec les opérateurs AND et OR. Les groupes de filtres peuvent être imbriqués pour des expressions complexes :

graphql
filter: {
  filterGroup: {
    operator: OR
    groups: [
      {
        operator: AND
        items: [
          { attribute: "status", operator: EQ, value: "active" }
          { attribute: "price", operator: GT, value: "100" }
        ]
      }
      {
        operator: AND
        items: [
          { attribute: "status", operator: EQ, value: "featured" }
        ]
      }
    ]
  }
}

Cet exemple retourne les produits qui sont soit (actifs ET chers) SOIT mis en avant.

Champs filtrables

Seuls les attributs marqués comme filterable: true dans le modèle peuvent être utilisés dans les expressions de filtre. Tenter de filtrer par un champ non filtrable n'a aucun effet. Configure les flags filtrables dans l'éditeur de tables du workspace.

Pagination

Mockomat utilise la pagination basée sur l'offset :

ParamètreDescriptionDéfaut
offsetNombre d'éléments à sauter0
limitNombre d'éléments à retourner20

Une requête paginée typique :

graphql
query {
  products(offset: 40, limit: 20) {
    id
    name
    price
  }
}

Cela retourne les éléments 41 à 60. Pour obtenir la page suivante, augmente l'offset de la valeur du limit.

Tri

Les champs marqués comme sortable: true dans le modèle peuvent être utilisés pour trier les résultats.

DirectionSignification
ASCCroissant (A→Z, 0→9, plus ancien→plus récent)
DESCDécroissant (Z→A, 9→0, plus récent→plus ancien)

Un seul champ de tri peut être appliqué par requête. Si aucun tri n'est spécifié, les résultats sont retournés dans leur ordre naturel de stockage.

Traversée des relations

L'une des fonctionnalités les plus puissantes du runtime est sa capacité à simuler des données relationnelles à partir de collections MongoDB plates.

Comment ça fonctionne

MongoDB stocke les données dans des collections dénormalisées — chaque enregistrement est un document plat sans jointures de clé étrangère. Le runtime simule les structures relationnelles en :

  1. Lisant la définition de relation depuis ton modèle (entité source, entité cible, cardinalité).
  2. Construisant des étapes de lookup dans la pipeline d'agrégation MongoDB qui joignent les collections liées.
  3. Assemblant les résultats imbriqués correspondant à la structure de réponse GraphQL.

Cela signifie que tes requêtes GraphQL se comportent comme si elles s'exécutaient contre une base de données entièrement relationnelle, bien que le stockage sous-jacent soit basé sur les documents.

Ce qu'il faut valider

Lors de la vérification de la traversée des relations :

  • Relations 1:1 devraient retourner un seul objet imbriqué (ou null s'il n'y a pas de correspondance).
  • Relations 1:n devraient retourner un tableau d'objets imbriqués.
  • Relations vides devraient retourner un tableau vide [], pas null.
  • Relations profondément imbriquées (ex. Customer → Order → OrderItem) devraient se résoudre correctement à chaque niveau.

Liste de contrôle du comportement des requêtes

Pour chaque entité clé de ton modèle, valide :

  • Stabilité des requêtes de liste — la même requête retourne-t-elle une structure cohérente lors d'appels répétés ?
  • Cohérence des éléments individuels — une requête de détail retourne-t-elle tous les champs attendus ?
  • Comportement des champs null et manquants — les champs optionnels sont-ils correctement représentés comme null ?
  • Traversée des relations — les objets imbriqués se résolvent-ils avec la cardinalité correcte ?
  • Précision des filtres — les expressions de filtre correspondent-elles au sous-ensemble attendu ?
  • Exactitude du tri — le tri produit-il un ordre prévisible et stable ?
  • Limites de pagination — offset et limit produisent-ils des tranches de page propres sans doublons ?
Screenshot rt-02-filter-sort-paginationScreenshot rt-02-filter-sort-pagination
rt-02-filter-sort-paginationMissing

Validation du comportement de filtrage, tri et pagination.

Inspection et débogage runtime

Lorsque le comportement semble incorrect, inspecte dans cet ordre :

1. Vérifier les définitions de tables et d'attributs

La cause la plus courante de comportement inattendu est un attribut mal configuré :

  • Le type de champ est-il correct ? (Un prix stocké comme string ne sera pas trié numériquement.)
  • Le champ est-il marqué comme triable/filtrable/recherchable ?
  • Le champ a-t-il une association configurée ?

2. Vérifier les métadonnées d'endpoint et de requête

Vérifie que la requête est correctement configurée dans la vue de conception API :

  • La requête est-elle activée ?
  • Le nom et les paramètres de la requête sont-ils corrects ?
  • La configuration de pagination est-elle appropriée ?

3. Vérifier l'état de l'association source

Si les champs retournent null ou des valeurs inattendues :

  • Le type d'association est-il correct (OFF_FIELD, FAKE, CONST) ?
  • Pour les associations OFF_FIELD, l'enregistrement source contient-il les données attendues ?
  • Pour les associations FAKE, le générateur Faker est-il configuré pour le bon type de données ?

4. Vérifier les politiques de relations

Si les données imbriquées sont manquantes ou incorrectes :

  • La direction de la relation est-elle correcte (source → cible) ?
  • La cardinalité correspond-elle (1:1 vs 1:n) ?
  • L'entité cible existe-t-elle et a-t-elle des données associées ?
  • Les colonnes de jointure sont-elles correctement spécifiées ?

Problèmes courants et solutions

SymptômeCause probableSolution
Réponse videAucune donnée importée pour cette collectionVérifier que l'import de données est terminé
Champs retournant nullAucune association configuréeAjouter une association OFF_FIELD, FAKE ou CONST
Relation imbriquée videRelation mal configuréeVérifier la direction, l'entité cible et les colonnes de jointure
Le tri ne fonctionne pasChamp non marqué comme triableActiver le flag triable dans l'éditeur de table
Le filtre retourne toutChamp non marqué comme filtrableActiver le flag filtrable dans l'éditeur de table
Types de données incorrectsDiscordance de type d'associationVérifier que l'association produit le type attendu
La pagination saute des élémentsErreur de calcul d'offsetVérifier que les incréments d'offset correspondent à la valeur du limit
Screenshot rt-03-runtime-inspectionScreenshot rt-03-runtime-inspection
rt-03-runtime-inspectionMissing

Flux d'inspection runtime et points de contrôle de débogage.

Validation avant export

Le runtime devrait confirmer la disponibilité avant de passer à la génération de code backend. Un modèle qui passe la validation runtime a significativement plus de chances de produire un backend généré propre et fonctionnel.

Critères de disponibilité

Avant l'export, confirme que :

  • Les champs obligatoires sont stables — tous les attributs obligatoires ont des valeurs cohérentes et non-null.
  • La surface d'opérations est intentionnelle — seules les requêtes que tu souhaites exposer sont activées.
  • Le comportement des relations est explicable — chaque requête imbriquée se résout correctement et la cardinalité correspond à tes règles métier.
  • Le comportement des filtres et du tri est prévisible — les consommateurs peuvent compter sur le fonctionnement documenté de ces opérations.
  • Aucune indication non résolue — la prévisualisation n'affiche aucun avertissement sur des attributs non associés ou une configuration manquante.

Workflow de validation pré-export

  1. Exécuter des requêtes de liste pour chaque entité — vérifier la structure et la qualité des données.
  2. Exécuter des requêtes de détail pour les entités clés — vérifier la complétude des champs.
  3. Tester tous les filtres configurés — vérifier le sous-ensemble correct.
  4. Tester le tri sur chaque champ triable — vérifier l'ordre.
  5. Tester les limites de pagination — vérifier les transitions de page propres.
  6. Tester les requêtes de relations imbriquées — vérifier l'assemblage correct à chaque niveau.
Screenshot rt-04-runtime-validationScreenshot rt-04-runtime-validation
rt-04-runtime-validationMissing

Résumé de validation runtime pré-export.