A Go-based weather API service that provides weather updates via email subscriptions. Users can subscribe to receive weather updates for their preferred cities either hourly or daily.
🚨 Please be aware that site is deployed at https://weatherapi-rpum.onrender.com (currently unavailable) 🚨
The project follows a clean architecture pattern with the following structure:
weather-api/
├── cmd/
│ └── server/ # Application entry point
├── internal/
│ ├── adapter/ # External service adapters (email, weather API, database)
│ ├── core/ # Domain models and business logic
│ ├── handler/ # HTTP handlers
│ ├── mocks/ # Mock implementations for testing
│ └── util/ # Utility functions and configuration
├── migrations/ # Database migrations
└── web/ # Frontend static files
- Weather Service: Fetches weather data from external weather API
- Email Service: Handles email notifications using SMTP
- Subscription Service: Manages user subscriptions and confirmation
- Token Service: Generates subscription tokens
- PostgreSQL Database: Stores subscription information
- Go 1.24
- PostgreSQL
- SMTP server access (google app generated pass)
- Weather API key (https://www.weatherapi.com)
Create a .env
file in the root directory with the following variables:
DB_CONN_STR=postgres://username:password@localhost:5432/weather_db?sslmode=disable
WEATHER_API_KEY=your_weather_api_key
BASE_URL=http://localhost:8080
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your_email@gmail.com
SMTP_PASS=your_app_specific_password
PORT=8080
- Start the server and postgres db using docker:
docker compose up -d
Migrations will be automatically applied upon lift. The server will start on port 8080 by default.
Run all tests:
go test ./...
Run tests only in core/service directory:
go test ./internal/core/service/...
Install golangci-lint:
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.1.6
Run the linter:
golangci-lint run -v
GET /api/weather
- Get current weather for a cityPOST /api/subscribe
- Subscribe to weather updatesGET /api/confirm/:token
- Confirm subscriptionGET /api/unsubscribe/:token
- Unsubscribe from updates
The service supports two types of update frequencies:
- Hourly Updates: Sent every hour
- Daily Updates: Sent once daily at 8:00 AM
Please be aware, that after click button Subscribe - on ui only button changes color and email sent, no alerts
To modify the update schedule, edit the cron expressions in cmd/server/main.go
:
cron.AddFunc("0 * * * *", func() { emailService.SendUpdates(context.Background(), domain.FrequencyHourly) })
cron.AddFunc("0 0 * * *", func() { emailService.SendUpdates(context.Background(), domain.FrequencyDaily) })
{
"email": "user@example.com",
"city": "Kyiv",
"frequency": "hourly"
}