0Pricing
React Academy · Aula

Formulários seguros quanto aos tipos e contratos de respostas de API

Use Zod para inferir tipos TypeScript a partir de esquemas e validar tanto dados de formulários quanto respostas de APIs.

Formulários seguros quanto aos tipos e contratos de respostas de API é uma aula grátis de React Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de React Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de React Academy inclui 4 aulas no total.

Por que formatos de dados seguros quanto aos tipos são importantes

Formulários e respostas de API são pontos de fronteira nos quais os dados entram na sua aplicação a partir de fontes não confiáveis. O Zod permite definir esquemas que validam em tempo de execução e também inferem tipos do TypeScript.

Noções básicas de esquemas do Zod

Defina esquemas com a API fluente do Zod. Use z.infer<typeof schema> para extrair o tipo do TypeScript.

import { z } from 'zod';

const UserSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(1).max(100),
  email: z.string().email(),
  age: z.number().int().min(0).max(150).optional(),
  role: z.enum(['admin', 'user', 'guest']),
});

type User = z.infer<typeof UserSchema>;
// { id: string; name: string; email: string; age?: number; role: 'admin'|'user'|'guest' }

React Hook Form com o resolvedor do Zod

Integre esquemas do Zod ao React Hook Form para obter validação de formulários segura quanto aos tipos — o TypeScript conhece o formato dos dados e dos erros do formulário.

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';

const LoginSchema = z.object({
  email: z.string().email('Invalid email'),
  password: z.string().min(8, 'At least 8 characters'),
});
type LoginData = z.infer<typeof LoginSchema>;

function LoginForm() {
  const { register, handleSubmit, formState: { errors } } = useForm<LoginData>({
    resolver: zodResolver(LoginSchema),
  });

  const onSubmit = (data: LoginData) => {
    // data is LoginData — fully typed, already validated
  };
}

Validando respostas de API

Analise as respostas da API com o Zod para detectar incompatibilidades de formato na fronteira — se a API retornar dados inesperados, você obterá um erro detalhado em vez de uma falha em tempo de execução no interior do seu componente.

async function fetchUser(id: string): Promise<User> {
  const res = await fetch(`/api/users/${id}`);
  const json = await res.json();
  return UserSchema.parse(json); // throws ZodError if shape is wrong
}

Análise segura para erros controlados

Use schema.safeParse() para obter um objeto de resultado em vez de lançar uma exceção — ideal para validação de formulários quando você deseja mostrar os erros ao usuário.

const result = UserSchema.safeParse(formData);
if (!result.success) {
  const errors = result.error.flatten().fieldErrors;
  // { name: ['Must be at least 1 character'], email: ['Invalid email'] }
  return errors;
}
const user = result.data; // User — fully typed

Uniões discriminadas com Zod

Utilize z.discriminatedUnion para modelar respostas de API com formatos diferentes, definidos por um indicador de sucesso ou erro.

const ApiResponse = z.discriminatedUnion('ok', [
  z.object({ ok: z.literal(true), data: UserSchema }),
  z.object({ ok: z.literal(false), error: z.string(), code: z.number() }),
]);

type ApiResult = z.infer<typeof ApiResponse>;
// { ok: true; data: User } | { ok: false; error: string; code: number }

Transformações com Zod

Utilize .transform() para converter ou remodelar dados durante a análise — por exemplo, converter uma cadeia de caracteres de data em um objeto Date.

const DateSchema = z.string().transform(s => new Date(s));
// Input: '2024-01-15' → Output: Date object

const EventSchema = z.object({
  title: z.string(),
  date: z.string().pipe(z.coerce.date()),
});
type Event = z.infer<typeof EventSchema>;
// { title: string; date: Date }

Reutilização de esquemas

Derive os esquemas de criação e atualização a partir do esquema base para evitar duplicação.

const UserSchema = z.object({ name: z.string(), email: z.string().email() });

// For creation: add password
const CreateUserSchema = UserSchema.extend({ password: z.string().min(8) });

// For update: all fields optional
const UpdateUserSchema = UserSchema.partial();

type CreateUser = z.infer<typeof CreateUserSchema>;
type UpdateUser = z.infer<typeof UpdateUserSchema>;

Ação do servidor com Zod

Valide os dados do formulário em uma ação do servidor do Next.js com Zod antes de acessar o banco de dados.

async function createPost(formData: FormData) {
  'use server';
  const schema = z.object({ title: z.string().min(3), body: z.string().min(10) });
  const result = schema.safeParse(Object.fromEntries(formData));
  if (!result.success) return { errors: result.error.flatten().fieldErrors };
  await db.post.create({ data: result.data });
  revalidatePath('/blog');
  redirect('/blog');
}

Esquemas compartilhados entre frontend e backend

Exporte os esquemas do Zod de um pacote compartilhado para que o frontend e o backend utilizem a mesma lógica de validação — um único esquema como fonte de verdade.

// packages/schemas/src/user.ts
export const CreateUserSchema = z.object({ ... });
export type CreateUser = z.infer<typeof CreateUserSchema>;

// Frontend imports:
import { CreateUserSchema, CreateUser } from '@company/schemas';
// Backend imports:
import { CreateUserSchema } from '@company/schemas';

Mensagens de erro do Zod

Personalize as mensagens de erro de cada campo para melhorar a experiência do usuário — o Zod as envia automaticamente para a exibição de erros do formulário por meio do resolvedor.

const RegistrationSchema = z.object({
  username: z.string()
    .min(3, 'Username must be at least 3 characters')
    .max(20, 'Username cannot exceed 20 characters')
    .regex(/^[a-z0-9_]+$/, 'Only lowercase letters, numbers, and underscores'),
});

Verificação rápida

O que z.infer<typeof MySchema> fornece no TypeScript?

Recapitulação

Defina os esquemas do Zod uma vez e utilize z.infer para derivar tipos do TypeScript. Utilize zodResolver no React Hook Form para obter uma validação segura em relação aos tipos. Analise as respostas da API com o Zod na fronteira do sistema, utilize safeParse para erros exibidos ao usuário e compartilhe os esquemas entre o frontend e o backend por meio de um pacote compartilhado.

Perguntas Frequentes

A aula “Formulários seguros quanto aos tipos e contratos de respostas de API” é grátis?

Sim — o texto completo de “Formulários seguros quanto aos tipos e contratos de respostas de API” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de React Academy, atualize para CoddyKit PRO. O curso de React Academy inclui 4 aulas no total.

O que vou aprender em “Formulários seguros quanto aos tipos e contratos de respostas de API”?

Use Zod para inferir tipos TypeScript a partir de esquemas e validar tanto dados de formulários quanto respostas de APIs. Você pratica React Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar React Academy?

Nenhuma experiência prévia é necessária. React Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Formulários seguros quanto aos tipos e contratos de respostas de API”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de React Academy?

Sim. Cada aula de React Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Uniões discriminadas para variantes de componentes
  2. Tipos condicionais e mapeados no React
  3. Componentes polimórficos com a propriedade 'as'
  4. Formulários seguros quanto aos tipos e contratos de respostas de API
← Voltar para React Academy