Blank white background with no objects or features visible.

Estamos disponibilizando acesso gratuito ao Gartner Hype Cycle for AI Governance 2026 completo. Obtenha sua cópia →

Formulários baseados em esquema no React: construindo com o FormBuilder do TrueFoundry

By Shubham Kumar Singh

Published: October 7, 2026

Se você já usou a TrueFoundry para implantar um serviço, criar um cluster, configurar um modelo de LLM ou gerenciar segredos, você interagiu com formulários que parecem uma interface comum, mas que são construídos de forma muito diferente dos formulários 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 que a TrueFoundry usa formulários baseados em esquema

Os formulários da TrueFoundry geralmente representam manifestos — objetos YAML/JSON que você também pode aplicar via CLI (tfy apply -f ...). O mesmo objeto pode ser editado na interface, baixado como YAML ou enviado para a API.

Uma abordagem baseada em esquema oferece à TrueFoundry:

  • Uma única fonte de verdade para a estrutura do formulário (carregada do backend por tipo de recurso).
  • Comportamento consistente em implantações, clusters, políticas, modelos, segredos, formulários de configurações ou qualquer outro formulário na plataforma.
  • Campos aninhados e condicionais sem a necessidade de reescrever a lógica do formulário em cada tela.
  • Widgets específicos de domínio (seletor de cluster, seletor de segredos, limites de recursos) conectados a um runtime compartilhado.

O modelo mental: o esquema descreve a forma dos dados e como editá-los; o FormBuilder transforma essa descrição em um formulário funcional.

1. Esquema do formulário:

Um esquema de formulário é uma matriz de definições de campo. Cada campo é um objeto com algumas propriedades 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.).

Aqui está um exemplo genérico simplificado — não é um esquema real da TrueFoundry, mas é próximo de como o produto entende a configuração:

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

Manifesto/configuração resultante no envio:

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

2. Como os componentes são mapeados e os campos são renderizados

A renderização ocorre em um pequeno pipeline, o fluxo é:

O FormBuilder percorre a árvore do esquema e escolhe um componente React por nó com base no uiType.

Tipos de componentes:

  • Básico: Input, Select, Radio, Switch, Number
  • Estrutural: Group (seção), Structs (lista repetível), KV / ENV (chave-valor)
  • Específicos de Domínio: ClusterSelect, SecretSelect, Resources, ModelSelect, PermissionsMatrix, campos MCP e mais

Condições: Se image.type !== "existing", o campo URI nunca é montado. Com shouldUnregister: true, ele também sai do estado do formulário, para que valores ocultos não vazem no payload.

Lógica de mapeamento no 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. Como o estado do formulário é gerenciado

O FormBuilder usa o react-hook-form como seu motor de estado. Essa escolha é fundamental para o comportamento do produto.

Inicialização/Uso do componente - criar e editar:

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

Configuração do formulário:

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

Registro de campos - cada input é vinculado ao seu caminho:

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

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

Contexto extra - formulários específicos transmitem dados de tempo de execução separados dos valores dos campos:

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

Objeto único, caminhos aninhados:

Todos os valores dos campos residem em um único objeto de formulário. Cada campo é registrado sob seu caminho jsonKey completo:

  • name → string de nível superior
  • image.type → valor aninhado
  • ports.0.container_port → primeiro item em um array

Ao editar um campo, você está alterando este objeto compartilhado. Ao enviar, o FormBuilder lê o objeto inteiro e o transmite para o manipulador do formulário (que geralmente chama a API da TrueFoundry ou gera YAML).

Padrões e modo de edição:

Ao abrir um formulário para criar algo, os defaultValues podem estar vazios ou vir de um modelo.

Ao editar, defaultValues geralmente é o manifesto existente. Os campos do formulário são preenchidos a partir desse objeto. Alguns campos são marcados como imutáveis no modo de edição (por exemplo, o nome do recurso), portanto, são exibidos como somente leitura.

Campos ocultos são removidos do estado:

Os formulários da TrueFoundry usam shouldUnregister: true. Isso significa que:

  • Se um campo for ocultado por uma condição, ele é removido do estado do formulário
  • Seu valor não vaza para o payload enviado

Isso é importante para formulários condicionais: você envia apenas o que o usuário realmente pôde ver e editar.

4. Como funciona a validação

A validação nos formulários da TrueFoundry ocorre em duas camadas.

Camada 1: Validação de esquema (declarativa)

O bloco validate de cada campo pode especificar:

  • required
  • min / max (intervalo permitido de valores inteiros)
  • minLength / maxLength (comprimento de string ou array)
  • pattern (regex) com mensagem personalizada
  • defaultValue
  • immutable (somente leitura no modo de edição)

Essas regras são convertidas em regras de validação do react-hook-form. Os erros são exibidos em linha ao lado do campo. A validação é executada na alteração (mode: 'onChange'), para que os usuários recebam feedback enquanto digitam, e não apenas ao enviar.

Camada 2: Validação personalizada e assíncrona

Os esquemas também podem anexar uma função de validação personalizada, comumente usada para:

  • Unicidade de nome (“Já existe uma entidade com este nome”)
  • Verificações via API antes do envio
  • Regras entre campos dentro de um componente personalizado
  • As telas anexam isso em tempo de execução com auxiliares como “anexar validação ao nome do campo”. A interface exibe um ícone de carregamento enquanto a validação assíncrona é executada (por exemplo, verificação de nome com debounce).
useAttachValidation(schema, {
  name: async (name) => {
    const taken = await checkNameExists(name)
    return taken ? 'Name already exists' : true
  },
})

Resumo: a experiência do usuário

Ao abrir “Criar Cluster”, “Implantar Serviço”, “Adicionar Modelo” ou “Gerenciar Segredos”:

  • O TrueFoundry carrega (ou cria) um esquema para esse recurso
  • O FormBuilder renderiza cada nó do esquema como o componente de entrada desejado
  • Suas edições atualizam um único objeto de formulário aninhado
  • A validação é executada continuamente e novamente no momento do envio
  • O objeto final é um manifesto - o mesmo formato que você usaria em YAML ou na CLI

É por isso que o TrueFoundry consegue oferecer suporte a interfaces de configuração muito complexas sem que cada tela seja um formulário exclusivo: a complexidade reside no esquema e em uma biblioteca de componentes de campo, orquestrados por um tempo de execução compartilhado.

Try now.

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

Start free
Table of Contents

One Gateway for Every LLM, Agent and MCP Server

Book a 30-min with our AI expert

Book a Demo

The fastest way to build, govern and scale your AI

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

Discover More

No items found.
OpenRouter pricing compared with TrueFoundry AI Gateway governance
October 14, 2026
|
5 min read

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

No items found.
October 10, 2026
|
5 min read

Claude Code --dangerously-skip-permissions Explicado: Riscos, Casos de Uso e Alternativas Mais Seguras

No items found.
October 7, 2026
|
5 min read

Melhor "Agent Harness" de Código Aberto: Comparativo dos 5 Principais Projetos para 2026

No items found.
July 21, 2026
|
5 min read

Limites do Claude Code Explicados (Edição 2026)

No items found.
No items found.

Recent Blogs

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

Frequently asked questions

Por que escolher uma abordagem orientada por esquema em vez de codificar formulários manualmente?

Formulários orientados por esquema fornecem uma fonte única da verdade para seus manifestos de configuração. Eles garantem um comportamento consistente da UI, suportam lógica aninhada/condicional sem código repetido e permitem que o backend defina a estrutura do formulário dinamicamente.

Como funciona a validação no FormBuilder?

A validação ocorre em duas camadas: validação de esquema declarativa (usando regras como obrigatório, padrão ou mínimo/máximo) e validação personalizada/assíncrona para verificações baseadas em API, como a verificação de nomes de recursos únicos.

Posso integrar isso com bibliotecas React existentes?

Sim. O FormBuilder da TrueFoundry usa o react-hook-form como seu motor de estado principal, tornando-o compatível com padrões React padrão e fácil de estender com componentes personalizados.

Take a quick product tour
Start Product Tour
Product Tour