# Como consumir API de CPF em Solid.js com createResource

> Aprenda a consumir a API de consulta de CPF da CPFHub.io em Solid.js usando createResource e SolidStart para validação reativa e server-side.

**Publicado:** 02/05/2026
**Autor:** Redação CPFHub.io
**URL:** https://cpfhub.io/blog/como-consumir-api-de-cpf-em-solid-js-com-createresource

---


O **Solid.js** é um framework reativo de alta performance para construção de interfaces. Com `createResource`, o Solid.js gerencia o ciclo de vida de chamadas assíncronas — incluindo estados de loading e erro — de forma declarativa. Combinado com server functions do SolidStart, a chave de API da CPFHub.io fica no servidor e a consulta retorna nome, gênero e data de nascimento do titular com latência de ~900ms.

---

## 1. Pré-requisitos

* **SolidStart** configurado com `npm create solid@latest`.

* Node.js 18+ instalado.

* Uma conta na [**CPFHub.io**](https://www.cpfhub.io/)

---

## 2. Configure a variável de ambiente

Crie o arquivo `.env` na raiz do projeto:

```
CPFHUB_API_KEY=SUA_CHAVE_DE_API
```

No SolidStart, variáveis sem prefixo `VITE_` ficam acessíveis apenas no servidor.

---

## 3. Server function para consulta segura

Crie uma server function que consulta a API da CPFHub.io. Ela roda exclusivamente no servidor, protegendo a chave de API. A documentação do SolidStart detalha o uso de server functions em [docs.solidjs.com](https://docs.solidjs.com/):

```typescript
// src/lib/cpfhub.ts
"use server";

export interface CpfData {
 cpf: string;
 name: string;
 nameUpper: string;
 gender: string;
 birthDate: string;
 day: number;
 month: number;
 year: number;
}

export interface CpfResponse {
 success: boolean;
 data: CpfData;
}

export async function consultarCpf(cpf: string): Promise<CpfResponse> {
 const cpfLimpo = cpf.replace(/\D/g, '');

 if (cpfLimpo.length !== 11) {
 throw new Error('CPF deve conter 11 dígitos');
 }

 const controller = new AbortController();
 const timeoutId = setTimeout(() => controller.abort(), 5000);

 try {
 const response = await fetch(`https://api.cpfhub.io/cpf/${cpfLimpo}`, {
 method: 'GET',
 headers: {
 'x-api-key': process.env.CPFHUB_API_KEY || '',
 'Accept': 'application/json'
 },
 signal: controller.signal
 });

 clearTimeout(timeoutId);

 if (!response.ok) {
 if (response.status === 401) throw new Error('Chave de API inválida');
 throw new Error(`Erro HTTP ${response.status}`);
 }

 return await response.json();
 } catch (error) {
 clearTimeout(timeoutId);
 throw error;
 }
}
```

---

## 4. Componente com createResource

O `createResource` do Solid.js reage a um sinal e executa uma função assíncrona automaticamente:

```typescript
// src/routes/cpf/[cpf].tsx
import { createResource, Show, Suspense } from 'solid-js';
import { useParams } from '@solidjs/router';
import { consultarCpf } from '~/lib/cpfhub';

export default function CpfPage() {
 const params = useParams();

 const [cpfData] = createResource(
 () => params.cpf,
 async (cpf) => {
 const resultado = await consultarCpf(cpf);
 return resultado;
 }
 );

 return (
 <div>
 <h2>Resultado da Validação</h2>

 <Suspense fallback={<p>Consultando CPF...</p>}>
 <Show when={cpfData()?.success} fallback={<p>CPF não encontrado.</p>}>
 <dl>
 <dt>CPF</dt>
 <dd>{cpfData()?.data.cpf}</dd>
 <dt>Nome</dt>
 <dd>{cpfData()?.data.name}</dd>
 <dt>Gênero</dt>
 <dd>{cpfData()?.data.gender === 'M' ? 'Masculino' : 'Feminino'}</dd>
 <dt>Data de Nascimento</dt>
 <dd>{cpfData()?.data.birthDate}</dd>
 </dl>
 </Show>
 </Suspense>

 <Show when={cpfData.error}>
 <p style="color: red;">Erro: {cpfData.error?.message}</p>
 </Show>
 </div>
 );
}
```

---

## 5. Formulário interativo com createSignal e createResource

Para um formulário de busca reativo:

```typescript
// src/routes/validar.tsx
import { createSignal, createResource, Show, Suspense } from 'solid-js';
import { consultarCpf } from '~/lib/cpfhub';

export default function ValidarPage() {
 const [cpfInput, setCpfInput] = createSignal('');
 const [cpfBusca, setCpfBusca] = createSignal<string | undefined>(undefined);

 const [resultado] = createResource(cpfBusca, async (cpf) => {
 if (!cpf) return null;
 return await consultarCpf(cpf);
 });

 function handleSubmit(e: Event) {
 e.preventDefault();
 const cpf = cpfInput().replace(/\D/g, '');
 if (cpf.length === 11) {
 setCpfBusca(cpf);
 }
 }

 return (
 <div>
 <h2>Validar CPF</h2>

 <form onSubmit={handleSubmit}>
 <label for="cpf">CPF:</label>
 <input
 type="text"
 id="cpf"
 value={cpfInput()}
 onInput={(e) => setCpfInput(e.currentTarget.value)}
 placeholder="Digite o CPF"
 maxLength={14}
 required
 />
 <button type="submit" disabled={resultado.loading}>
 {resultado.loading ? 'Consultando...' : 'Validar'}
 </button>
 </form>

 <Suspense fallback={<p>Carregando...</p>}>
 <Show when={resultado()?.success}>
 <dl>
 <dt>Nome</dt>
 <dd>{resultado()?.data.name}</dd>
 <dt>CPF</dt>
 <dd>{resultado()?.data.cpf}</dd>
 <dt>Data de Nascimento</dt>
 <dd>{resultado()?.data.birthDate}</dd>
 </dl>
 </Show>
 </Suspense>

 <Show when={resultado.error}>
 <p style="color: red;">Erro: {resultado.error?.message}</p>
 </Show>
 </div>
 );
}
```

---

## 6. API route com SolidStart

Para expor um endpoint REST na aplicação SolidStart:

```typescript
// src/routes/api/cpf/[cpf].ts
import type { APIEvent } from '@solidjs/start/server';
import { consultarCpf } from '~/lib/cpfhub';

export async function GET(event: APIEvent) {
 const cpf = event.params.cpf;

 try {
 const resultado = await consultarCpf(cpf);
 return new Response(JSON.stringify(resultado), {
 headers: { 'Content-Type': 'application/json' }
 });
 } catch (error) {
 return new Response(
 JSON.stringify({ error: error instanceof Error ? error.message : 'Erro' }),
 { status: 502, headers: { 'Content-Type': 'application/json' } }
 );
 }
}
```

Teste com:

```bash
curl -X GET http://localhost:3000/api/cpf/12345678900 \
 -H "Accept: application/json"
```

---

## 7. Exemplo de resposta da API

A API da [**CPFHub.io**](https://www.cpfhub.io/) retorna um JSON padronizado em todas as consultas:

```json
{
 "success": true,
 "data": {
 "cpf": "12345678900",
 "name": "João da Silva",
 "nameUpper": "JOÃO DA SILVA",
 "gender": "M",
 "birthDate": "15/06/1990",
 "day": 15,
 "month": 6,
 "year": 1990
 }
}
```

---

## 8. Boas práticas

* **"use server"** — Marque funções que acessam a chave de API com a diretiva `"use server"` para garantir que o código rode exclusivamente no servidor.

* **Timeout** — O `AbortController` com 5 segundos evita que o `createResource` fique pendente indefinidamente.

* **Suspense** — Use `<Suspense>` para mostrar feedback de carregamento enquanto o recurso é resolvido.

* **Reatividade** — O `createResource` reexecuta automaticamente quando o sinal de entrada muda, evitando chamadas manuais.

* **Plano gratuito** — O plano gratuito inclui 50 consultas/mês. Ao ultrapassar o limite, a API não bloqueia: cobra R$0,15 por consulta adicional. Para produção, o plano Pro (R$149/mês) oferece 1.000 consultas.

---

## Perguntas frequentes

### Por que usar createResource em vez de fetch direto no componente Solid.js?

O `createResource` integra o carregamento assíncrono ao sistema reativo do Solid.js: ele expõe estados de `loading` e `error` automaticamente, e reexecuta quando o sinal de entrada muda. Um fetch manual exige que você gerencie esses estados com `createSignal` e `createEffect`, aumentando a complexidade do código sem ganho real.

### Como a diretiva "use server" protege a chave de API da CPFHub.io?

Funções marcadas com `"use server"` são excluídas do bundle do cliente pelo SolidStart durante o build. O browser recebe apenas o resultado da chamada — nunca o código que contém `process.env.CPFHUB_API_KEY`. Sem essa diretiva, a chave poderia aparecer no JavaScript enviado ao navegador.

### O que acontece com o createResource se a API demorar mais que o esperado?

A latência média da CPFHub.io é ~900ms. O `AbortController` configurado com 5 segundos de timeout cancela a requisição caso ela ultrapasse esse limite, e o `createResource` entra no estado de erro — que pode ser capturado via `cpfData.error` e exibido ao usuário. Sem timeout, o componente ficaria no estado de `loading` indefinidamente.

### O plano gratuito bloqueia a aplicação ao atingir o limite de consultas?

Não. Quando o limite de 50 consultas mensais é atingido, a API continua funcionando normalmente — cada consulta adicional é cobrada a R$0,15. A [ANPD](https://www.gov.br/anpd) recomenda que dados pessoais sejam consultados apenas quando houver base legal, o que também ajuda a controlar o volume de requisições e os custos.

### 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)
- [Como consumir API de CPF em TypeScript com tipagem segura](https://cpfhub.io/blog/como-consumir-api-de-cpf-em-typescript-com-tipagem-segura)
- [Boas práticas para consumir APIs de CPF de forma segura](https://cpfhub.io/blog/boas-praticas-consumir-apis-cpf-segura)
- [Como consumir API de CPF em NestJS com módulos e providers](https://cpfhub.io/blog/como-consumir-api-de-cpf-em-nestjs-com-modulos-e-providers)

---

## Conclusão

O Solid.js com `createResource` e SolidStart oferece uma integração reativa e segura com a API da [**CPFHub.io**](https://www.cpfhub.io/). A primitiva `createResource` cuida dos estados de loading e erro, enquanto as server functions garantem que a chave de API nunca seja exposta ao cliente.

Cadastre-se em [cpfhub.io](https://www.cpfhub.io/) para obter sua chave gratuitamente e começar a validar CPFs em minutos.

