Skip to content
This repository was archived by the owner on Jun 14, 2025. It is now read-only.

Commit 4a44690

Browse files
committed
feat(i18n): Implement Google Translate integration with caching
- Added Google Translate API client with caching support using Redis or in-memory cache. - Created translation request and response structures for handling API interactions. - Implemented translation service interface and mock service for testing. - Developed translation cache with expiration and cleanup mechanisms. - Introduced middleware for language detection based on request headers and query parameters. - Added comprehensive tests for translation services and middleware functionality. - Included localization support with JSON files for multiple languages (en, pt-BR, es, fr, de, it). - Established a Redis-based translation cache for persistent storage of translations.
1 parent ff46dc5 commit 4a44690

32 files changed

+3576
-43
lines changed

README.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# AstroVista API
2+
3+
API para gerenciar dados da NASA APOD (Astronomy Picture of the Day) com recursos avançados de documentação interativa, sistema de cache e suporte a múltiplos idiomas.
4+
5+
## Recursos
6+
7+
- **Documentação interativa** com Swagger/OpenAPI
8+
- **Sistema de cache** com Redis para melhor performance
9+
- **Internacionalização (i18n)** com suporte a múltiplos idiomas - Inglês (padrão)
10+
- Português do Brasil
11+
- Espanhol
12+
- Francês
13+
- Alemão
14+
- Italiano
15+
- Suporte para adicionar novos idiomas facilmente
16+
17+
## Configuração
18+
19+
### Requisitos
20+
21+
- Go 1.18 ou superior
22+
- MongoDB (para armazenamento de dados)
23+
- Redis (opcional, para cache)
24+
25+
### Variáveis de ambiente
26+
27+
- `PORT` - Porta do servidor (padrão: 8081)
28+
- `MONGODB_URI` - URI de conexão com o MongoDB
29+
- `REDIS_URL` - URL do servidor Redis (opcional)
30+
- `REDIS_PASSWORD` - Senha do Redis (opcional)
31+
- `GOOGLE_TRANSLATE_API_KEY` - Chave da API do Google Translate (opcional)
32+
- `DEEPL_API_KEY` - Chave da API DeepL para traduções (opcional)
33+
34+
## Serviços de Tradução
35+
36+
A API pode utilizar diferentes serviços de tradução:
37+
38+
### Google Translate
39+
40+
Para usar o Google Translate, você precisa:
41+
42+
1. Criar uma conta no [Google Cloud Platform](https://cloud.google.com/)
43+
2. Criar um novo projeto
44+
3. Ativar a Cloud Translation API
45+
4. Criar uma chave de API
46+
5. Definir a variável de ambiente `GOOGLE_TRANSLATE_API_KEY`
47+
48+
```bash
49+
export GOOGLE_TRANSLATE_API_KEY="sua-chave-aqui"
50+
```
51+
52+
### DeepL
53+
54+
Para usar o DeepL, você precisa:
55+
56+
1. Criar uma conta no [DeepL API](https://www.deepl.com/pro-api)
57+
2. Obter sua chave de autenticação
58+
3. Definir a variável de ambiente `DEEPL_API_KEY`
59+
60+
```bash
61+
export DEEPL_API_KEY="sua-chave-aqui"
62+
```
63+
64+
### Simulação (Mock)
65+
66+
Se nenhuma chave de API for configurada, a API usará um serviço de tradução simulado para desenvolvimento.
67+
68+
## Sistema de Cache de Traduções
69+
70+
Para melhorar a performance e evitar requisições repetidas às APIs de tradução, implementamos um sistema de cache em dois níveis:
71+
72+
1. **Cache em memória**: Armazena traduções recentes na memória para acesso rápido
73+
2. **Cache Redis**: Se o Redis estiver disponível, as traduções também são armazenadas de forma persistente
74+
75+
As traduções são armazenadas por 30 dias no cache Redis, reduzindo significativamente o número de chamadas às APIs externas.
76+
77+
## Executando a API
78+
79+
```bash
80+
# Clone o repositório
81+
git clone https://github.com/seu-usuario/astrovista-api.git
82+
cd astrovista-api
83+
84+
# Instale as dependências
85+
go get -u
86+
87+
# Execute a API
88+
go run main.go
89+
```
90+
91+
## Endpoints
92+
93+
### Documentação
94+
95+
- `/swagger/` - Documentação interativa Swagger
96+
97+
### Principais endpoints
98+
99+
- `GET /apod` - Obtém o APOD mais recente
100+
- `GET /apod/{date}` - Obtém um APOD por data específica
101+
- `GET /apods` - Lista todos os APODs cadastrados
102+
- `GET /apods/search` - Pesquisa avançada com filtros
103+
- `GET /apods/date-range` - Busca APODs por intervalo de datas
104+
- `GET /languages` - Lista idiomas suportados
105+
- `POST /apod` - Adiciona um novo APOD
106+
107+
## Suporte a idiomas
108+
109+
Para obter respostas em um idioma específico, você pode:
110+
111+
1. Enviar o cabeçalho `Accept-Language` na requisição
112+
113+
```
114+
Accept-Language: pt-BR
115+
```
116+
117+
2. Ou adicionar o parâmetro `lang` na URL
118+
```
119+
/apod?lang=pt-BR
120+
```
121+
122+
## Cache
123+
124+
As respostas da API incluem o cabeçalho `X-Cache` para indicar se o resultado veio do cache:
125+
126+
- `X-Cache: HIT` - Resposta recuperada do cache
127+
- `X-Cache: MISS` - Resposta obtida do banco de dados
128+
129+
## Licença
130+
131+
MIT

astrovista-api.exe

30.2 MB
Binary file not shown.

cache/redis.go

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package cache
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"log"
7+
"os"
8+
"time"
9+
10+
"github.com/go-redis/redis/v8"
11+
)
12+
13+
var (
14+
// Client é o cliente Redis compartilhado
15+
Client *redis.Client
16+
// DefaultExpiration é o tempo padrão de expiração para itens em cache (24 horas)
17+
DefaultExpiration = 24 * time.Hour
18+
)
19+
20+
// Connect estabelece a conexão com o Redis
21+
func Connect() {
22+
// Verifica se há um URL do Redis nas variáveis de ambiente (para uso em produção)
23+
redisURL := os.Getenv("REDIS_URL")
24+
25+
// Se não houver, usa um padrão para desenvolvimento local
26+
if redisURL == "" {
27+
redisURL = "localhost:6379"
28+
}
29+
30+
// Configuração do cliente Redis
31+
Client = redis.NewClient(&redis.Options{
32+
Addr: redisURL,
33+
Password: os.Getenv("REDIS_PASSWORD"), // Sem senha se não estiver definido
34+
DB: 0, // Usar banco de dados 0
35+
})
36+
// Verifica se a conexão está funcionando
37+
ctx := context.Background()
38+
_, err := Client.Ping(ctx).Result()
39+
if err != nil {
40+
log.Printf("Aviso: Não foi possível conectar ao Redis: %v", err)
41+
log.Println("O cache será desativado. Para ativar o cache, instale o Redis e execute-o em localhost:6379")
42+
log.Println("A API continuará funcionando normalmente, mas sem o benefício do cache")
43+
Client = nil
44+
return
45+
}
46+
47+
log.Println("Conexão com Redis estabelecida com sucesso")
48+
}
49+
50+
// Set armazena um item no cache
51+
func Set(ctx context.Context, key string, value interface{}, expiration time.Duration) error {
52+
if Client == nil {
53+
return nil // Cache desativado
54+
}
55+
56+
// Convertendo para JSON
57+
data, err := json.Marshal(value)
58+
if err != nil {
59+
return err
60+
}
61+
62+
// Armazenando no Redis
63+
return Client.Set(ctx, key, data, expiration).Err()
64+
}
65+
66+
// Get recupera um item do cache
67+
func Get(ctx context.Context, key string, dest interface{}) (bool, error) {
68+
if Client == nil {
69+
return false, nil // Cache desativado
70+
}
71+
72+
// Buscando do Redis
73+
data, err := Client.Get(ctx, key).Bytes()
74+
if err == redis.Nil {
75+
// Item não encontrado no cache
76+
return false, nil
77+
} else if err != nil {
78+
// Erro ao acessar o Redis
79+
return false, err
80+
}
81+
82+
// Convertendo de JSON para o tipo de destino
83+
if err := json.Unmarshal(data, dest); err != nil {
84+
return false, err
85+
}
86+
87+
return true, nil
88+
}
89+
90+
// Delete remove um item do cache
91+
func Delete(ctx context.Context, key string) error {
92+
if Client == nil {
93+
return nil // Cache desativado
94+
}
95+
96+
return Client.Del(ctx, key).Err()
97+
}
98+
99+
// Clear limpa todo o cache
100+
func Clear(ctx context.Context) error {
101+
if Client == nil {
102+
return nil // Cache desativado
103+
}
104+
105+
return Client.FlushAll(ctx).Err()
106+
}

0 commit comments

Comments
 (0)