Projeto focado em consumo e tratamento de dados estruturados (JSON) de fontes externas.
Aplicação React inspirada no desafio “REST Countries API”, com busca, filtro por região e página de detalhes do país.
Este repositório foi pensado como um projeto de portfólio que evidencia Data Ingestion no frontend:
- Consumo de uma API pública (REST Countries)
- Tratamento do JSON (normalização, limpeza e padronização)
- Resiliência (cache e fallback offline)
- Consumo do “contrato de dados” normalizado nos componentes
O ponto central aqui é a ingestão de dados: o app consome uma API pública de países (REST Countries), recebe um JSON com estrutura extensa e transforma esse JSON em um formato estável para uso na UI.
Na prática, isso demonstra o tipo de trabalho que analistas e engenheiros de dados fazem o tempo todo ao integrar fontes externas: padronizar campos, tratar nulos, lidar com variações de schema e manter uma camada de dados consistente.
O pipeline de ingestão foi isolado em uma camada própria para deixar o projeto mais profissional e fácil de evoluir:
- Ingestão (API externa) com timeout e tratamento de erro
- Normalização do JSON para um “schema” interno estável
- Deduplicação e ordenação
- Cache (localStorage) com TTL para reduzir chamadas
- Fallback para dataset local (modo offline / GitHub Pages)
Arquivos principais:
loadCountries()busca na API externa (/all?fields=...)- Se falhar, faz fallback para
public/data.json normalizeCountries()aplica limpeza + padronização + dedupe + sort- O hook
useCountries()expõe{ countries, loading, error }para a UI - Componentes consomem apenas o schema normalizado, evitando transformação espalhada
O JSON da API pode variar (ex.: versões diferentes retornam formatos distintos). A normalização garante que a UI sempre receba algo consistente:
name: pode vir como string (v2) ou como objeto (name.common/name.officialem v3)capital: pode ser string (v2) ou array (v3)languages: pode ser array de objetos (v2) ou objeto-chave/valor (v3)currencies: pode ser array (v2) ou objeto (v3)flags: pode vir comoflags.png/svg(v2) ouflaglegado
Além disso, o pipeline trata qualidade de dados para evitar quebras comuns:
- Campos ausentes viram valores default (ex.:
population: 0, listas vazias) - Conversões seguras (string/array → string, object → array,
Number(...)com fallback) - Deduplicação por
alpha3Code(quando disponível) e ordenação porname
Schema normalizado (campos usados pela UI):
name,alpha3Code,nativeNameregion,capital,populationtopLevelDomainlanguages(lista de strings)currenciesCodebordersflags(png/svg)
Esse “contrato de dados” é o que os componentes usam, independentemente do formato exato retornado pela fonte.
Se a API estiver indisponível (ou sem rede), o app tenta carregar public/data.json para manter a experiência funcionando.
O resultado da API é cacheado em localStorage com TTL de 24h para reduzir chamadas e deixar a navegação mais fluida.
Caso você queira forçar um recarregamento (sem cache), existe clearCountriesCache() no service.
Pré-requisitos: Node.js + npm
- Instalar dependências:
npm install - Ambiente dev:
npm start - Build produção:
npm run build - Testes:
npm test -- --watchAll=false
npm start: servidor de desenvolvimentonpm test -- --watchAll=false: testes em modo CInpm run build: build de produçãonpm run deploy: publica no GitHub Pages
Este projeto está configurado para deploy via gh-pages.
- Gere o build:
npm run build - Publique:
npm run deploy
Observação: o campo homepage em package.json está configurado para funcionar com GitHub Pages.
Você pode apontar para outro endpoint base via variável de ambiente:
REACT_APP_COUNTRIES_API_BASE(padrão:https://restcountries.com/v2)
Exemplo:
REACT_APP_COUNTRIES_API_BASE=https://restcountries.com/v2 npm start
- React 18 (Create React App)
- React Router v6
- Reactstrap + Bootstrap + Bulma
- Fetch API
- src/services/countriesIngestion.js: ingestão, fallback, normalização e cache
- src/hooks/useCountries.js: estado de loading/erro + entrega do dataset para UI
- src/Components/content.jsx: busca e filtro em cima do dataset normalizado
- src/Components/Details.jsx: detalhes consumindo somente o schema normalizado
- Busca por país
- Filtro por região
- Página de detalhes
- Tema dark/light
O texto do UI está em inglês por conta do desafio original, mas o foco deste repositório é a parte de ingestão e tratamento de dados (JSON) para consumo no frontend.
Alguns pacotes do ecossistema do CRA podem emitir warnings de depreciação em versões mais novas do Node; o build funciona normalmente.
