React com JSON Server: Crie um CRUD sem Precisar de um Backend
Você está desenvolvendo uma aplicação em React, mas o backend ainda não está pronto?
Isso não significa que o desenvolvimento do frontend precisa parar.
Uma das possibilidades é utilizar o JSON Server para criar uma API REST simulada e continuar desenvolvendo e testando sua aplicação React normalmente.
Neste projeto vamos construir um Gerenciador de Tarefas com React e JSON Server, utilizando uma estrutura que permite posteriormente substituir a API simulada por um backend real sem precisar reconstruir toda a aplicação.
O que é JSON Server?
Durante o desenvolvimento de uma aplicação frontend, nem sempre temos uma API real disponível.
Imagine uma equipe em que o frontend e o backend estão sendo desenvolvidos simultaneamente.
O desenvolvedor frontend precisa criar:
- componentes;
- formulários;
- listagens;
- validações;
- integração com API;
- tratamento dos dados.
Mas os endpoints do backend ainda não estão disponíveis.
Em vez de esperar, podemos trabalhar com uma API simulada.
É exatamente aí que entra o JSON Server.
A arquitetura utilizada durante o desenvolvimento pode ser representada assim:
React
↓
Service
↓
HTTP
↓
JSON Server
↓
db.json
O React continua realizando requisições HTTP normalmente.
A diferença é que, em vez de uma API desenvolvida em Node.js, Java, PHP, Python, C# ou outra tecnologia, quem responde temporariamente às requisições é o JSON Server.
Projeto: Gerenciador de Tarefas
Para colocar esse conceito em prática, desenvolvemos um pequeno Gerenciador de Tarefas.
A aplicação permite:
- listar tarefas;
- cadastrar novas tarefas;
- marcar uma tarefa como concluída;
- reabrir uma tarefa;
- excluir tarefas;
- confirmar antes da exclusão;
- manter os dados armazenados no
db.json.
Apesar de ser uma aplicação simples, ela permite trabalhar vários conceitos importantes do desenvolvimento com React.
Tecnologias utilizadas
Neste projeto utilizamos:
- React;
- Vite;
- JavaScript;
- JSON Server;
- Fetch API;
- HTML;
- CSS.
Também trabalhamos conceitos importantes do React, como:
- componentes;
useState;useEffect;- props;
- eventos;
- renderização de listas;
- atualização de estado;
- comunicação com uma API.
O arquivo db.json
O JSON Server utiliza um arquivo JSON como base para os dados.
No nosso projeto temos uma estrutura semelhante a esta:
{
"tarefas": [
{
"id": 1,
"titulo": "Estudar React",
"concluida": false
},
{
"id": 2,
"titulo": "Aprender JSON Server",
"concluida": true
}
]
}
A partir desse pequeno arquivo, conseguimos trabalhar com endpoints HTTP.
Por exemplo:
GET /tarefas
POST /tarefas
PATCH /tarefas/:id
DELETE /tarefas/:id
Isso permite que nossa aplicação React trabalhe como se estivesse consumindo uma API REST.
GET: buscando as tarefas
Para buscar as tarefas utilizamos uma requisição GET.
const resposta = await fetch(
"http://localhost:3001/tarefas"
);
const dados = await resposta.json();
Os dados recebidos podem então ser armazenados em um estado:
setTarefas(dados);
Na aplicação utilizamos também o useEffect para realizar o carregamento inicial dos dados.
useEffect(() => {
carregarTarefas();
}, []);
Assim, quando o componente é carregado, o React solicita os dados da nossa API simulada.
POST: cadastrando uma nova tarefa
Para cadastrar uma tarefa utilizamos o método HTTP POST.
const resposta = await fetch(
"http://localhost:3001/tarefas",
{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
titulo: titulo,
concluida: false
})
}
);
Aqui aparecem conceitos importantes quando trabalhamos com APIs:
- método HTTP;
- cabeçalhos;
Content-Type;- corpo da requisição;
- conversão de objetos JavaScript para JSON.
PATCH: atualizando uma tarefa
Quando queremos alterar apenas parte de um recurso podemos utilizar PATCH.
No nosso exemplo, precisamos alterar apenas a propriedade:
concluida
Podemos enviar:
{
concluida: true
}
para:
PATCH /tarefas/1
Dessa maneira conseguimos marcar uma tarefa como concluída ou reabri-la.
DELETE: excluindo uma tarefa
Para remover uma tarefa utilizamos:
DELETE /tarefas/:id
Por exemplo:
await fetch(
`http://localhost:3001/tarefas/${id}`,
{
method: "DELETE"
}
);
Antes de realizar a exclusão, nossa aplicação também solicita uma confirmação do usuário.
const confirmar = window.confirm(
"Tem certeza que deseja excluir esta tarefa?"
);
if (!confirmar) {
return;
}
Esse pequeno detalhe evita exclusões acidentais e também permite discutir boas práticas de interface com o usuário.
Organizando a comunicação com a API
Um ponto importante do projeto é não espalhar chamadas fetch() por todos os componentes.
Criamos uma camada de serviço:
src/
├── components/
│ ├── Header.jsx
│ ├── Footer.jsx
│ ├── FormTarefa.jsx
│ └── ListaTarefas.jsx
│
├── services/
│ └── tarefaService.js
│
├── App.jsx
└── main.jsx
O arquivo:
tarefaService.js
fica responsável pela comunicação com a API.
Assim podemos ter funções como:
buscarTarefas();
criarTarefa();
atualizarStatus();
excluirTarefa();
Os componentes não precisam conhecer todos os detalhes da comunicação HTTP.
Temos então:
COMPONENTES REACT
↓
APP
↓
tarefaService.js
↓
API
Por que separar o Service?
Essa separação se torna especialmente interessante quando pensamos na evolução de uma aplicação.
Hoje podemos ter:
React
↓
Service
↓
JSON Server
Amanhã podemos substituir por:
React
↓
Service
↓
Node.js + Express
↓
Banco de Dados
Ou até:
React
↓
Service
↓
Java + Spring
O frontend não deveria precisar conhecer a tecnologia utilizada internamente pelo backend.
O importante é conhecer o contrato da API.
Se os endpoints e os dados esperados continuarem compatíveis, grande parte da aplicação React pode permanecer exatamente igual.
O frontend não precisa esperar o backend
Esse talvez seja o conceito mais importante deste projeto.
Em projetos reais, frontend e backend podem ser desenvolvidos simultaneamente.
O desenvolvedor frontend não deveria precisar ficar parado esperando toda a implementação do servidor ficar pronta.
Podemos definir previamente como será a comunicação:
GET /tarefas
POST /tarefas
PATCH /tarefas/:id
DELETE /tarefas/:id
e qual será a estrutura dos dados:
{
"id": 1,
"titulo": "Estudar React",
"concluida": false
}
Com esse contrato definido, podemos criar uma API simulada e desenvolver o frontend.
Posteriormente, o mock é substituído pela API real.
Código completo no GitHub
O projeto completo utilizado neste artigo está disponível gratuitamente no GitHub.
No repositório você encontrará o código React, os componentes, o Service, o arquivo db.json e a implementação do CRUD com JSON Server.
Acesse o projeto:
https://github.com/marcoscaldas/ReactComJSONServer
O repositório também possui versões do projeto que podem ser utilizadas para acompanhar o desenvolvimento passo a passo.
Depois:
npm install
Para iniciar o JSON Server:
npm run server
Em outro terminal, execute o React:
npm run dev
Em breve: live com o projeto completo
🎥 Em breve teremos uma live completa no canal Desvendando o Código desenvolvendo este projeto passo a passo.
Na live vamos entender como utilizar o JSON Server como uma API simulada, consumir os dados com React e construir as operações de um CRUD utilizando GET, POST, PATCH e DELETE.
Assim que a aula estiver disponível, o vídeo será adicionado aqui ao artigo.
Conclusão
JSON Server não substitui o aprendizado de desenvolvimento backend.
A proposta é outra.
Ele permite simular uma API durante o desenvolvimento do frontend.
Isso possibilita desenvolver componentes, telas, formulários e integrações sem precisar esperar que uma API real esteja completamente implementada.
Neste projeto utilizamos:
React
↓
Service
↓
JSON Server
↓
db.json
Mas futuramente podemos evoluir para:
React
↓
Service
↓
API REST real
↓
Backend
↓
Banco de Dados
E é justamente essa separação que permite que frontend e backend evoluam de maneira independente.
Se você está aprendendo React, clone o projeto, volte para a versão inicial e tente reconstruir o CRUD antes de consultar a versão final.
É uma ótima forma de praticar.


