Aprenda / Frontend — Tailwind & Next.js

IntermediárioAula 15 de 2015 min0% da trilha

Server Actions: mutação sem API route

Antes, toda mutação exigia criar uma API route e chamar fetch nela. Agora um form pode chamar uma função de servidor direto.

Historicamente, qualquer mutação — criar, editar, apagar algo — significava criar um endpoint (route.ts) e chamar ele via fetch do client, como no projeto guiado da lição 10. Server Actions permitem pular essa etapa: uma função marcada com "use server" pode ser chamada direto por um componente, inclusive como action de um <form>.

"use server" — uma função que roda no servidor

app/tarefas/actions.ts
"use server";

import { revalidatePath } from "next/cache";

export async function criarTarefa(formData: FormData) {
  const titulo = formData.get("titulo") as string;
  if (!titulo || titulo.length < 3) throw new Error("Título muito curto");

  await db.tarefa.create({ data: { titulo } });
  revalidatePath("/tarefas"); // invalida o cache da rota, próxima visita busca dado novo
}

Essa função nunca vira JavaScript enviado ao navegador — o Next.js gera, por baixo dos panos, uma requisição que executa ela no servidor. revalidatePath avisa o Next que os dados daquela rota mudaram, sem você reimplementar cache manualmente.

Form chamando a Server Action direto

app/tarefas/nova-tarefa-form.tsx
import { criarTarefa } from "./actions";

export function NovaTarefaForm() {
  return (
    <form action={criarTarefa} className="flex gap-2">
      <input name="titulo" placeholder="Nova tarefa" className="flex-1 border rounded-lg px-3 py-2" />
      <button type="submit" className="bg-blue-600 text-white px-4 py-2 rounded-lg">
        Adicionar
      </button>
    </form>
  );
}

Repare que NovaTarefaForm nem precisa de "use client" aqui — não há onSubmit, useState nem fetch manual. O action={criarTarefa} é a submissão real do formulário; o Next.js conecta isso à Server Action.

Quando ainda faz sentido ter uma API route de verdade

Server Actions são pensadas pra mutações chamadas pela sua própria UI React. Uma API route continua sendo a peça certa quando quem consome a mutação não é o seu próprio app Next — um webhook de um serviço de pagamento, um aplicativo mobile separado, uma integração pública de terceiros. Nesses casos você precisa de uma URL HTTP estável e documentável, não de uma função interna do seu bundle.

Exercício

Pegue o NovaTarefaForm da lição 10, que faz fetch("https://api.exemplo.com/tarefas", { method: "POST" }) dentro de um onSubmit num Client Component, e reescreva-o usando Server Action.

Quiz rápido

O que a diretiva "use server" marca?
Quando ainda faz sentido criar uma API route em vez de usar só Server Actions?