Blank white background with no objects or features visible.

Te ofrecemos acceso gratuito al informe completo Gartner Hype Cycle for AI Governance 2026. Consigue tu copia →

Formularios basados en esquemas en React: construyendo con TrueFoundry FormBuilder

Por Shubham Kumar Singh

Published: October 7, 2026

Si has utilizado TrueFoundry para desplegar un servicio, crear un clúster, configurar un modelo LLM o gestionar secretos, habrás interactuado con formularios que parecen interfaces normales, pero que están construidos de forma muy distinta a los formularios web típicos.

⚡ 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

Por qué TrueFoundry utiliza formularios basados en esquemas

Los formularios de TrueFoundry suelen representar manifiestos: objetos YAML/JSON que también puedes aplicar con la CLI (tfy apply -f ...). El mismo objeto puede editarse en la interfaz, descargarse como YAML o enviarse a la API.

Un enfoque basado en esquemas proporciona a TrueFoundry:

  • Una única fuente de verdad para la estructura del formulario (cargada desde el backend según el tipo de recurso).
  • Un comportamiento coherente en despliegues, clústeres, políticas, modelos, secretos, formularios de configuración o cualquier otro formulario de la plataforma.
  • Campos anidados y condicionales sin tener que reescribir la lógica del formulario en cada pantalla.
  • Widgets específicos del dominio (selector de clúster, selector de secretos, límites de recursos) integrados en un entorno de ejecución compartido.

El modelo mental: el esquema describe la forma de los datos y cómo editarlos; FormBuilder convierte esa descripción en un formulario funcional.

1. Esquema del formulario:

Un esquema de formulario es una matriz de definiciones de campo. Cada campo es un objeto con algunas propiedades 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.).

Aquí tienes un ejemplo genérico simplificado; no es un esquema real de TrueFoundry, pero se acerca a cómo el producto entiende la configuración:

[
  {
    "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 }
      }
    ]
  }
]

Manifiesto/configuración resultante al enviar:

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

2. Cómo se asignan los componentes y se renderizan los campos

El renderizado ocurre en una pequeña tubería; el flujo es el siguiente:

FormBuilder recorre el árbol del esquema y elige un componente de React por nodo basándose en uiType.

Tipos de componentes:

  • Básicos: Input, Select, Radio, Switch, Number
  • Estructurales: Group (sección), Structs (lista repetible), KV / ENV (clave-valor)
  • Específicos del dominio: ClusterSelect, SecretSelect, Resources, ModelSelect, PermissionsMatrix, campos MCP y más

Condiciones: Si image.type !== "existing", el campo URI nunca se monta. Con shouldUnregister: true, también sale del estado del formulario, por lo que los valores ocultos no pueden filtrarse en el payload.

Lógica de mapeo en el código:

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

if (!enabledByCondition) return null

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

3. Cómo se gestiona el estado del formulario

FormBuilder utiliza react-hook-form como motor de estado. Esa elección es fundamental para el comportamiento del producto.

Inicialización/Uso del componente - crear y editar:

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

Configuración del formulario:

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

Registro de campos: cada entrada se vincula a su ruta:

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

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

Contexto adicional: formularios específicos pasan datos en tiempo de ejecución separados de los valores de los campos:

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

Objeto único, rutas anidadas:

Todos los valores de los campos residen en un único objeto de formulario. Cada campo se registra bajo su ruta jsonKey completa:

  • name → cadena de nivel superior
  • image.type → valor anidado
  • ports.0.container_port → primer elemento de una matriz

Al editar un campo, estás modificando este objeto compartido. Al enviar, FormBuilder lee el objeto completo y lo pasa al manejador del formulario (que normalmente llama a la API de TrueFoundry o genera YAML).

Valores predeterminados y modo de edición:

Al abrir un formulario para crear algo, los defaultValues pueden estar vacíos o provenir de una plantilla.

Al editar, defaultValues suele ser el manifiesto existente. Los campos del formulario se rellenan previamente a partir de ese objeto. Algunos campos se marcan como inmutables en el modo de edición (por ejemplo, el nombre del recurso), por lo que aparecen como de solo lectura.

Los campos ocultos se eliminan del estado:

Los formularios de TrueFoundry utilizan shouldUnregister: true. Esto significa que:

  • Si un campo está oculto por una condición, se anula su registro en el estado del formulario
  • Su valor no se filtra en la carga útil enviada

Esto es importante para los formularios condicionales: solo se envía lo que el usuario realmente pudo ver y editar.

4. Cómo funciona la validación

La validación en los formularios de TrueFoundry se realiza en dos niveles.

Nivel 1: Validación de esquema (declarativa)

El bloque validate de cada campo puede especificar:

  • required
  • min / max (rango permitido de valores enteros)
  • minLength / maxLength (longitud de cadena o matriz)
  • pattern (regex) con mensaje personalizado
  • defaultValue
  • immutable (solo lectura en modo edición)

Estas reglas se convierten en reglas de validación de react-hook-form. Los errores se muestran en línea junto al campo. La validación se ejecuta al cambiar (modo: 'onChange'), por lo que los usuarios reciben comentarios mientras escriben, no solo al enviar.

Nivel 2: Validación personalizada y asíncrona

Los esquemas también pueden adjuntar una función de validación personalizada, utilizada habitualmente para:

  • Unicidad del nombre ("Ya existe una entidad con este nombre")
  • Comprobaciones mediante API antes del envío
  • Reglas entre campos dentro de un componente personalizado
  • Las pantallas los vinculan en tiempo de ejecución con asistentes como “vincular validación al nombre del campo”. La interfaz muestra un indicador de carga mientras se ejecuta la validación asíncrona (por ejemplo, una comprobación de nombre con debounce).
useAttachValidation(schema, {
  name: async (name) => {
    const taken = await checkNameExists(name)
    return taken ? 'Name already exists' : true
  },
})

Resumen: lo que experimentas como usuario

Cuando abres “Crear clúster”, “Desplegar servicio”, “Añadir modelo” o “Gestionar secretos”:

  • TrueFoundry carga (o construye) un esquema para ese recurso
  • FormBuilder renderiza cada nodo del esquema como el componente de entrada deseado
  • Tus ediciones actualizan un único objeto de formulario anidado
  • La validación se ejecuta de forma continua y de nuevo al enviar
  • El objeto final es un manifiesto: la misma estructura que usarías en YAML o en la CLI

Es por eso que TrueFoundry puede admitir interfaces de configuración muy complejas sin que cada pantalla sea un formulario único: la complejidad reside en el esquema y en una biblioteca de componentes de campo, orquestados por un tiempo de ejecución compartido.

Try now.

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

Inscríbase
Tabla de contenido

Controle, implemente y rastree la IA en su propia infraestructura

Reserva 30 minutos con nuestro Experto en IA

Reserve una demostración

La forma más rápida de crear, gobernar y escalar su IA

Demo del libro
Summarize with
ChatGPT logo by OpenAI
Perplexity AI logo
Blurry red snowflake on white background, symmetrical frosty design with soft edges and abstract shape.

Descubra más

No se ha encontrado ningún artículo.
OpenRouter pricing compared with TrueFoundry AI Gateway governance
October 14, 2026
|
5 minutos de lectura

OpenRouter Pricing in 2026: Full Breakdown of Plans, Costs, and Hidden Fees

No se ha encontrado ningún artículo.
October 10, 2026
|
5 minutos de lectura

Explicación del Código Claude: saltarse peligrosamente los permisos: riesgos, casos de uso y alternativas más seguras

No se ha encontrado ningún artículo.
October 7, 2026
|
5 minutos de lectura

El mejor «agent harness» de código abierto: comparativa de los 5 mejores proyectos para 2026

No se ha encontrado ningún artículo.
July 21, 2026
|
5 minutos de lectura

Explicación de los límites del código Claude (edición 2026)

No se ha encontrado ningún artículo.
No se ha encontrado ningún artículo.

Blogs recientes

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

Preguntas frecuentes

¿Por qué elegir un enfoque impulsado por esquemas en lugar de codificar formularios manualmente?

Los formularios impulsados por esquemas proporcionan una única fuente de verdad para sus manifiestos de configuración. Garantizan un comportamiento uniforme de la interfaz de usuario, permiten lógica anidada/condicional sin código repetido y posibilitan que el backend defina la estructura del formulario de forma dinámica.

¿Cómo funciona la validación en FormBuilder?

La validación se realiza en dos capas: validación declarativa de esquema (utilizando reglas como obligatorio, patrón o mín/máx) y validación personalizada/asíncrona para comprobaciones respaldadas por API, como la verificación de nombres de recursos únicos.

¿Puedo integrar esto con bibliotecas de React existentes?

Sí. El FormBuilder de TrueFoundry utiliza react-hook-form como su motor de estado principal, lo que lo hace compatible con los patrones estándar de React y fácil de extender con componentes personalizados.

Realice un recorrido rápido por el producto
Comience el recorrido por el producto
Visita guiada por el producto