# Como usar Server Actions do Next.js para consultar CPF via API

> Aprenda a usar Server Actions do Next.js para consultar CPF via API sem criar Route Handlers, com validação e feedback.

**Publicado:** 09/12/2024
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-usar-server-actions-nextjs-consultar-cpf-api

---


Server Actions são funções assíncronas do Next.js executadas no servidor e chamadas diretamente de componentes React, eliminando a necessidade de Route Handlers ou endpoints de API manuais. Com elas, a chave de API fica protegida no servidor, o código fica mais conciso e a integração com a [API de CPF da CPFHub.io](https://www.cpfhub.io/) se reduz a poucas linhas. Esta abordagem é ideal para validação de CPF em formulários de cadastro, checkout e onboarding digital.

## Introdução

Server Actions são uma funcionalidade do Next.js que permite executar código no servidor diretamente a partir de componentes React, sem a necessidade de criar Route Handlers ou endpoints de API manualmente. Essa abordagem simplifica a integração com APIs externas como o CPFHub.io, mantendo a chave de API segura e reduzindo a quantidade de código necessário.

## O que são Server Actions

Server Actions são funções assíncronas executadas no servidor que podem ser chamadas diretamente de componentes React. Elas são marcadas com a diretiva `'use server'`.

```javascript
// actions/cpf-actions.js
'use server';

export async function consultarCpf(cpf) {
 const cpfLimpo = cpf.replace(/\D/g, '');

 if (cpfLimpo.length !== 11) {
 return { success: false, error: 'CPF deve conter 11 dígitos' };
 }

 const response = await fetch(
 `${process.env.CPFHUB_BASE_URL}/cpf/${cpfLimpo}`,
 {
 headers: {
 'x-api-key': process.env.CPFHUB_API_KEY,
 },
 }
 );

 if (!response.ok) {
 return { success: false, error: 'CPF não encontrado' };
 }

 const dados = await response.json();

 if (!dados.success) {
 return { success: false, error: 'CPF não encontrado na base' };
 }

 return {
 success: true,
 data: {
 cpf: dados.data.cpf,
 nome: dados.data.name,
 nomeUpper: dados.data.nameUpper,
 genero: dados.data.gender,
 dataNascimento: dados.data.birthDate,
 dia: dados.data.day,
 mes: dados.data.month,
 ano: dados.data.year,
 },
 };
}
```

| Característica | Server Actions | Route Handlers |
|---|---|---|
| Arquivo separado | Não obrigatório | Sim (route.js) |
| Chamada do cliente | Direta (como função) | Via fetch |
| Segurança da API Key | Sim (servidor) | Sim (servidor) |
| Serialização | Automática | Manual (JSON) |
| Formulários nativos | Suporte total | Não aplicável |
| Código necessário | Menos | Mais |

---

## Server Action com validação completa

Crie uma Server Action que realiza validação algorítmica antes de consultar a API:

```javascript
// actions/cpf-actions.js
'use server';

function validarDigitosCpf(cpf) {
 const digitos = cpf.split('').map(Number);
 if (new Set(digitos).size === 1) return false;

 let soma = 0;
 for (let i = 0; i < 9; i++) soma += digitos[i] * (10 - i);
 const d1 = soma % 11 < 2 ? 0 : 11 - (soma % 11);

 soma = 0;
 for (let i = 0; i < 10; i++) soma += digitos[i] * (11 - i);
 const d2 = soma % 11 < 2 ? 0 : 11 - (soma % 11);

 return digitos[9] === d1 && digitos[10] === d2;
}

export async function validarEConsultarCpf(formData) {
 const cpf = formData.get('cpf');
 const cpfLimpo = cpf.replace(/\D/g, '');

 if (cpfLimpo.length !== 11) {
 return {
 success: false,
 etapa: 'formato',
 error: 'CPF deve conter 11 dígitos',
 };
 }

 if (!validarDigitosCpf(cpfLimpo)) {
 return {
 success: false,
 etapa: 'digitos',
 error: 'Dígitos verificadores inválidos',
 };
 }

 try {
 const response = await fetch(
 `${process.env.CPFHUB_BASE_URL}/cpf/${cpfLimpo}`,
 {
 headers: { 'x-api-key': process.env.CPFHUB_API_KEY },
 }
 );

 if (!response.ok) {
 return {
 success: true,
 etapa: 'api',
 formatoValido: true,
 encontrado: false,
 message: 'CPF válido, porém não encontrado na base',
 };
 }

 const dados = await response.json();

 return {
 success: true,
 etapa: 'completa',
 formatoValido: true,
 encontrado: dados.success,
 data: dados.success ? dados.data : null,
 };
 } catch {
 return {
 success: false,
 etapa: 'api',
 error: 'Erro ao consultar API externa',
 };
 }
}
```

---

## Usando Server Actions com useActionState

O hook `useActionState` do React permite gerenciar o estado de Server Actions de forma elegante:

```jsx
// components/CpfConsultaForm.jsx
'use client';

import { useActionState } from 'react';
import { validarEConsultarCpf } from '@/actions/cpf-actions';

const initialState = { success: null, data: null, error: null };

export default function CpfConsultaForm() {
 const [state, formAction, isPending] = useActionState(
 validarEConsultarCpf,
 initialState
 );

 return (
 <div className="max-w-lg mx-auto p-6">
 <h2 className="text-xl font-bold mb-4">Consulta de CPF</h2>

 <form action={formAction} className="space-y-4">
 <div>
 <label htmlFor="cpf" className="block text-sm font-medium mb-1">
 CPF
 </label>
 <input
 id="cpf"
 name="cpf"
 type="text"
 maxLength={14}
 placeholder="000.000.000-00"
 required
 className="w-full p-3 border rounded"
 />
 </div>

 <button
 type="submit"
 disabled={isPending}
 className="w-full p-3 bg-blue-600 text-white rounded disabled:opacity-50"
 >
 {isPending ? 'Consultando...' : 'Consultar CPF'}
 </button>
 </form>

 {state.success === true && state.data && (
 <div className="mt-6 p-4 bg-green-50 border border-green-200 rounded">
 <h3 className="font-bold mb-2">Dados encontrados</h3>
 <p><strong>Nome:</strong> {state.data.name}</p>
 <p><strong>CPF:</strong> {state.data.cpf}</p>
 <p><strong>Nascimento:</strong> {state.data.birthDate}</p>
 <p><strong>Genero:</strong> {state.data.gender}</p>
 </div>
 )}

 {state.success === true && !state.encontrado && (
 <div className="mt-6 p-4 bg-yellow-50 border border-yellow-200 rounded">
 <p>{state.message}</p>
 </div>
 )}

 {state.success === false && (
 <div className="mt-6 p-4 bg-red-50 border border-red-200 rounded">
 <p className="text-red-700">{state.error}</p>
 </div>
 )}
 </div>
 );
}
```

---

## Server Action para processamento em lote

Crie uma Server Action que processa múltiplos CPFs:

```javascript
// actions/cpf-lote-actions.js
'use server';

export async function processarLoteCpf(formData) {
 const cpfsTexto = formData.get('cpfs');
 const cpfs = cpfsTexto
 .split('\n')
 .map((l) => l.trim().replace(/\D/g, ''))
 .filter((l) => l.length === 11);

 if (cpfs.length === 0) {
 return { success: false, error: 'Nenhum CPF válido encontrado' };
 }

 if (cpfs.length > 20) {
 return { success: false, error: 'Máximo de 20 CPFs por lote' };
 }

 const resultados = await Promise.allSettled(
 cpfs.map(async (cpf) => {
 const response = await fetch(
 `${process.env.CPFHUB_BASE_URL}/cpf/${cpf}`,
 {
 headers: { 'x-api-key': process.env.CPFHUB_API_KEY },
 }
 );

 if (!response.ok) {
 return { cpf, encontrado: false };
 }

 const dados = await response.json();
 return {
 cpf,
 encontrado: dados.success,
 nome: dados.success ? dados.data.name : null,
 dataNascimento: dados.success ? dados.data.birthDate : null,
 };
 })
 );

 return {
 success: true,
 total: cpfs.length,
 resultados: resultados.map((r) =>
 r.status === 'fulfilled'
 ? r.value
 : { cpf: 'desconhecido', encontrado: false, erro: 'Falha na consulta' }
 ),
 };
}
```

---

## Página completa com Server Actions

Monte a página que integra todos os componentes:

```jsx
// app/consulta/page.jsx

import CpfConsultaForm from '@/components/CpfConsultaForm';

export const metadata = {
 title: 'Consulta de CPF | Minha Aplicação',
 description: 'Consulte dados de CPF de forma rápida e segura',
};

export default function ConsultaPage() {
 return (
 <main className="min-h-screen bg-gray-50 py-12">
 <div className="container mx-auto">
 <h1 className="text-3xl font-bold text-center mb-8">
 Consulta de CPF
 </h1>
 <CpfConsultaForm />
 </div>
 </main>
 );
}
```

---

## Perguntas frequentes

### O que são Server Actions no Next.js e como diferem de Route Handlers?
Server Actions são funções assíncronas marcadas com `'use server'` que executam no servidor e podem ser chamadas diretamente de componentes React — inclusive em atributos `action` de formulários nativos. Diferente de Route Handlers (arquivos `route.js`), não exigem um endpoint HTTP separado: o Next.js serializa automaticamente a chamada, reduzindo boilerplate e mantendo a API key fora do bundle do cliente.

### Como proteger a chave de API da CPFHub.io ao usar Server Actions?
Armazene a chave em variáveis de ambiente sem o prefixo `NEXT_PUBLIC_` (por exemplo, `CPFHUB_API_KEY`). O Next.js nunca inclui variáveis sem esse prefixo no bundle do cliente. Como a Server Action executa apenas no servidor, a chave nunca é exposta ao navegador — mesmo que o componente que chama a action seja renderizado no cliente.

### A API da CPFHub.io pode retornar erro 429 se eu ultrapassar o limite do plano gratuito?
Não. A API da CPFHub.io não retorna HTTP 429 nem bloqueia requisições ao atingir a cota do plano gratuito (50 consultas/mês). Consultas excedentes são cobradas automaticamente a R$0,15 cada. Para acompanhar o consumo e gerenciar o faturamento, acesse [app.cpfhub.io/settings/billing](https://app.cpfhub.io/settings/billing).

### Como usar `useActionState` com Server Actions para feedback visual?
Importe `useActionState` de `'react'` e passe sua Server Action como primeiro argumento, seguido do estado inicial. O hook retorna `[state, formAction, isPending]`: `state` contém o retorno da última execução, `formAction` é passado ao atributo `action` do formulário e `isPending` indica se a action está em andamento — ideal para desabilitar o botão de submit durante a consulta. A [documentação oficial do Next.js](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations) cobre o padrão completo com exemplos.

### Leia também

- [Como validar CPF no frontend com React e API REST](https://cpfhub.io/blog/como-validar-cpf-no-frontend-com-react-e-api-rest)
- [SLA de API de CPF: níveis de disponibilidade e o que exigir do seu provedor](https://cpfhub.io/blog/sla-api-cpf-niveis-disponibilidade)
- [API de CPF grátis para desenvolvedores: como começar em 5 minutos](https://cpfhub.io/blog/api-cpf-gratis-desenvolvedores-comecar-5-minutos)
- [10 erros mais comuns ao integrar uma API de CPF e como evitá-los](https://cpfhub.io/blog/10-erros-mais-comuns-ao-integrar-uma-api-de-cpf)

---

## Conclusão

Server Actions do Next.js simplificam drasticamente a integração com APIs externas. Sem necessidade de Route Handlers, o código fica mais conciso e a chave de API permanece segura no servidor. A integração com `useActionState` proporciona gerenciamento de estado elegante e feedback visual automático durante o processamento.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) — 50 consultas mensais gratuitas, sem cartão de crédito — e comece a usar Server Actions com validação de CPF em minutos, sem configurar nenhum endpoint de API.

