Blank white background with no objects or features visible.

Nous vous offrons un accès gratuit à l'intégralité du Gartner Hype Cycle for AI Governance 2026. Obtenez votre exemplaire →

Formulaires pilotés par schéma dans React : construire avec TrueFoundry FormBuilder

Par Shubham Kumar Singh

Published: October 6, 2026

Si vous avez déjà utilisé TrueFoundry pour déployer un service, créer un cluster, configurer un modèle LLM ou gérer des secrets, vous avez interagi avec des formulaires qui semblent classiques, mais qui sont conçus très différemment des formulaires web habituels.

⚡ TL;DR

TrueFoundry’s FormBuilder is a schema-driven form system that uses structured JSON to automatically render dynamic React inputs, groups, and validation logic. This architecture ensures consistent behavior across complex resource configurations, simplifies nested state management using react-hook-form, and allows for rapid development of domain-specific UIs. TrueFoundry does not hand-code every field on every screen. Instead, it uses a schema-driven form system called FormBuilder. A form is defined as structured JSON (the schema). The UI reads that schema and renders the right inputs, groups, validations, and conditional fields automatically.

This post explains how that works, in four parts:
  • What a form schema looks like
  • How fields are mapped to UI components and rendered
  • How form state is managed
  • How validation works

Pourquoi TrueFoundry utilise des formulaires basés sur des schémas

Les formulaires TrueFoundry représentent souvent des manifestes, c'est-à-dire des objets YAML/JSON que vous pouvez également appliquer via l'interface de ligne de commande (tfy apply -f ...). Le même objet peut être modifié dans l'interface utilisateur, téléchargé au format YAML ou soumis à l'API.

Une approche basée sur des schémas offre à TrueFoundry :

  • Une source unique de vérité pour la structure des formulaires (chargée depuis le backend en fonction du type de ressource).
  • Un comportement cohérent pour les déploiements, les clusters, les politiques, les modèles, les secrets, les formulaires de paramètres ou tout autre formulaire de la plateforme.
  • Des champs imbriqués et conditionnels sans avoir à réécrire la logique de formulaire sur chaque écran.
  • Des widgets spécifiques au domaine (sélecteur de cluster, sélecteur de secret, limites de ressources) intégrés à un runtime partagé.

Le modèle mental : le schéma décrit la forme des données et la manière de les modifier ; FormBuilder transforme cette description en un formulaire fonctionnel.

1. Schéma de formulaire :

Un schéma de formulaire est un tableau de définitions de champs. Chaque champ est un objet possédant quelques propriétés importantes :

Property Purpose
jsonKey Where this field lives in the submitted object (supports nesting, e.g. image.build_source.type).
label What the user sees.
uiType Which UI component to render (text input, select, group, custom widget, etc.).
sort Display order.
validate Required, min/max, pattern, defaults, custom validators.
conditions Show/hide or enable/disable based on other fields.
subParameters Child fields for groups and repeated sections.
uiProps Extra options passed to the component (search, table view, etc.).

Voici un exemple générique simplifié ; il ne s'agit pas d'un véritable schéma TrueFoundry, mais il illustre la manière dont le produit conçoit la configuration :

[
  {
    "sort": 1,
    "jsonKey": "name",
    "label": "Service Name",
    "uiType": "Input",
    "validate": { "required": true, "pattern": "^[a-z0-9-]+$" }
  },
  {
    "sort": 2,
    "jsonKey": "image",
    "label": "Image",
    "uiType": "Group",
    "subParameters": [
      {
        "jsonKey": "type",
        "label": "Source",
        "uiType": "Radio",
        "validate": {
          "required": true,
          "defaultValue": "build",
          "options": [
            { "label": "Build", "value": "build" },
            { "label": "Existing image", "value": "existing" }
          ]
        }
      },
      {
        "jsonKey": "uri",
        "label": "Image URI",
        "uiType": "Input",
        "conditions": [
 		{ "jsonKey": "image.type", "op": "==", "value": "existing"  }
  ],
        "validate": { "required": true }
      }
    ]
  }
]

Manifeste/configuration résultant lors de la soumission :

{
  "name": "my-service",
  "image": { "type": "existing", "uri": "registry.io/app:v1" }
}

2. Comment les composants sont mappés et les champs rendus

Le rendu s'effectue via un petit pipeline, selon le flux suivant :

FormBuilder parcourt l'arborescence du schéma et sélectionne un composant React par nœud en fonction du uiType.

Types de composants:

  • Basique : Input, Select, Radio, Switch, Number
  • Structurel : Group (section), Structs (liste répétable), KV / ENV (clé-valeur)
  • Spécifique au domaine : ClusterSelect, SecretSelect, Resources, ModelSelect, PermissionsMatrix, champs MCP, et plus encore

Conditions: Si image.type !== "existing", le champ URI n'est jamais monté. Avec shouldUnregister: true, il est également supprimé de l'état du formulaire, empêchant ainsi les valeurs masquées de s'infiltrer dans la charge utile.

Logique de mappage dans le code :

// FormComponentMap
const ComponentType = FormComponents[schema.uiType]
const CustomComp = CustomComponentsMap?.[schema.uiType]

if (!enabledByCondition) return null

return CustomComp
  ? <CustomComp schema={schema} />
  : <ComponentType schema={schema} />

3. Gestion de l'état du formulaire

FormBuilder utilise react-hook-form comme moteur d'état. Ce choix est déterminant pour le comportement du produit.

Initialisation/Utilisation des composants - création et modification :

<FormBuilder
  schema={schema}
  defaultValues={existingManifest}   // edit: pre-fill; create: empty/template
  onSubmit={(manifest) => createOrUpdate({ manifest })}
/>

Configuration du formulaire :

const methods = useForm({
  mode: 'onChange',          // validate as user types
  defaultValues,
  shouldUnregister: true,    // hidden fields drop out of state
})

Enregistrement des champs - chaque entrée est liée à son chemin :

// Inside a text field component
const { register } = useFormContext()

<input
  {...register(schema.jsonKey, registerProps)}
  defaultValue={defaultValue}
/>

Contexte supplémentaire - le formulaire spécifique transmet des données d'exécution distinctes des valeurs des champs :

<FormBuilder
  schema={schema}
  extraContext={{
    workspace,
    cluster,
    serviceAccountOptions,  // dynamic dropdown options
    dataTestPrefix: 'create-cluster',
  }}
/>

Objet unique, chemins imbriqués :

Toutes les valeurs des champs résident dans un objet de formulaire unique. Chaque champ s'enregistre sous son chemin jsonKey complet :

  • name → chaîne de caractères de premier niveau
  • image.type → valeur imbriquée
  • ports.0.container_port → premier élément d'un tableau

Lorsque vous modifiez un champ, vous modifiez cet objet partagé. Lors de la soumission, FormBuilder lit l'objet complet et le transmet au gestionnaire du formulaire (qui appelle généralement l'API TrueFoundry ou génère du YAML).

Valeurs par défaut et mode édition :

Lors de l'ouverture d'un formulaire pour créer un élément, les defaultValues peuvent être vides ou provenir d'un modèle.

Lors de la modification, defaultValues correspond généralement au manifeste existant. Les champs du formulaire sont pré-remplis à partir de cet objet. Certains champs sont marqués comme immuables en mode édition (par exemple, le nom de la ressource) et s'affichent donc en lecture seule.

Les champs masqués sont supprimés de l'état :

Les formulaires TrueFoundry utilisent shouldUnregister: true. Cela signifie que :

  • Si un champ est masqué par une condition, il est désenregistré de l'état du formulaire
  • Sa valeur n'est pas incluse dans la charge utile soumise

Ceci est important pour les formulaires conditionnels : vous ne soumettez que ce que l'utilisateur a pu réellement voir et modifier.

4. Fonctionnement de la validation

La validation dans les formulaires TrueFoundry s'effectue à deux niveaux.

Niveau 1 : Validation du schéma (déclarative)

Le bloc validate de chaque champ peut spécifier :

  • required
  • min / max (plage autorisée pour une valeur entière)
  • minLength / maxLength (longueur d'une chaîne ou d'un tableau)
  • pattern (regex) avec message personnalisé
  • defaultValue
  • immutable (lecture seule en mode édition)

Ces règles sont converties en règles de validation react-hook-form. Les erreurs s'affichent en ligne à côté du champ. La validation s'exécute lors du changement (mode : 'onChange'), afin que les utilisateurs reçoivent un retour au fur et à mesure de leur saisie, et non uniquement lors de la soumission.

Niveau 2 : Validation personnalisée et asynchrone

Les schémas peuvent également inclure une fonction de validation personnalisée, couramment utilisée pour :

  • L'unicité du nom (« Une entité portant ce nom existe déjà »)
  • Vérifications via API avant soumission
  • Règles inter-champs au sein d'un composant personnalisé
  • Les écrans les associent au moment de l'exécution grâce à des fonctions d'assistance telles que « attacher la validation au nom du champ ». L'interface affiche un indicateur de chargement pendant que la validation asynchrone s'exécute (par exemple, une vérification de nom avec debounce).
useAttachValidation(schema, {
  name: async (name) => {
    const taken = await checkNameExists(name)
    return taken ? 'Name already exists' : true
  },
})

En résumé : l'expérience utilisateur

Lorsque vous ouvrez « Créer un cluster », « Déployer un service », « Ajouter un modèle » ou « Gérer les secrets » :

  • TrueFoundry charge (ou génère) un schéma pour cette ressource
  • FormBuilder affiche chaque nœud du schéma sous forme de composant de saisie approprié
  • Vos modifications mettent à jour un objet de formulaire imbriqué unique
  • La validation s'exécute en continu, puis à nouveau lors de la soumission
  • L'objet final est un manifeste, présentant la même structure que celle utilisée dans un fichier YAML ou via l'interface en ligne de commande (CLI)

C'est pourquoi TrueFoundry peut prendre en charge des interfaces de configuration très complexes sans que chaque écran ne soit un formulaire spécifique : la complexité réside dans le schéma et dans une bibliothèque de composants de champs, orchestrés par un moteur d'exécution partagé.

Try now.

One gateway for all your models, MCP servers, and agents.
No credit card needed.

INSCRIVEZ-VOUS
Table des matières

Gouvernez, déployez et suivez l'IA dans votre propre infrastructure

Réservez un séjour de 30 minutes avec notre Expert en IA

Réservez une démo

Le moyen le plus rapide de créer, de gérer et de faire évoluer votre IA

Démo du livre
Summarize with
ChatGPT logo by OpenAI
Perplexity AI logo
Blurry red snowflake on white background, symmetrical frosty design with soft edges and abstract shape.

Découvrez-en plus

Aucun article n'a été trouvé.
October 10, 2026
|
5 min de lecture

10 meilleurs outils LLmops en 2026

comparaison
October 10, 2026
|
5 min de lecture

5 leçons sur l'exploitation d'IA agentique en production - D'après la discussion au coin du feu

Aucun article n'a été trouvé.
October 10, 2026
|
5 min de lecture

Passer à zéro dans Kubernetes : une plongée approfondie dans Elasti

Ingénierie et produits
October 10, 2026
|
5 min de lecture

L'observabilité dans les flux de travail LLM : transformer les boîtes noires en boîtes en verre

Aucun article n'a été trouvé.
Aucun article n'a été trouvé.

Blogs récents

Black left pointing arrow symbol on white background, directional indicator.
Black left pointing arrow symbol on white background, directional indicator.

Questions fréquemment posées

Pourquoi choisir une approche pilotée par un schéma plutôt que de coder les formulaires manuellement ?

Les formulaires pilotés par un schéma constituent une source unique de vérité pour vos manifestes de configuration. Ils garantissent un comportement cohérent de l'interface utilisateur, prennent en charge la logique imbriquée/conditionnelle sans duplication de code, et permettent au backend de piloter la structure du formulaire de manière dynamique.

Comment fonctionne la validation dans FormBuilder ?

La validation s'effectue sur deux niveaux : la validation de schéma déclarative (utilisant des règles comme obligatoire, motif ou min/max) et la validation personnalisée/asynchrone pour les contrôles adossés à une API, tels que la vérification de noms de ressources uniques.

Puis-je l'intégrer avec des bibliothèques React existantes ?

Oui. Le FormBuilder de TrueFoundry utilise react-hook-form comme moteur d'état principal, ce qui le rend compatible avec les modèles React standards et facile à étendre avec des composants personnalisés.

Faites un rapide tour d'horizon des produits
Commencer la visite guidée du produit
Visite guidée du produit