Nordic Weather is a secure, rate-limited weather data API built with Spring Boot. It fetches weather data from the Visual Crossing API, supports JWT-based authentication, uses Redis for caching, and applies Bucket4j for rate limiting.
This project demonstrates how to securely integrate third-party APIs into a Spring application with proper exception handling, rate limiting, caching strategies, and user authentication.
- Fetch weather data via third-party API (Visual Crossing)
- JWT-based user registration and login
- Redis-backed caching
- Bucket4j rate limiting
- Exception handling
- Configurable with environment variables or properties
- Clean architecture using Spring Boot best practices
- Java
- Spring (Spring Boot, Spring Security)
- Maven
- Bucket4j (rate limiting)
- Redis (cache)
- PostgreSQL (database)
- JWT (authentication)
- Java
- Maven
- Redis server
- PostgreSQL server
- A Visual Crossing API key
-
Clone the repository
git clone https://github.com/anilbolat/nordic-weather.git cd nordic-weather -
Install dependencies:
mvn clean install
-
Set your weather API key into environment variables or edit application.properties:
weather.api.key=${WEATHER_API_KEY:your_weather_api_key} -
Run the application:
mvn spring-boot:run # mvn org.springframework.boot:spring-boot-maven-plugin:3.3.5:run
- URL:
POST /api/v1/auth/register - Request Body:
{ "email": "exampleEmail", "password": "examplePassword", "firstName": "exampleFirstName", "lastName": "exampleLastName" } - Response:
201 Created: User successfully registered400 Bad Request: Invalid input or Already authenticated
- URL:
POST /api/v1/auth/login - Request Body:
{ "email": "exampleEmail", "password": "examplePassword" } - Response:
200 OK: Returns a JWT401 Unauthorized: Invalid credentials
- URL:
/api/v1/weather - Method:
GET - Query Parameters:
location(required): e.g.Tamperedate(required):2025-08-14(format: yyyy-MM-dd)
- Response:
200 OK: Returns the weather data.400 Bad Request: Invalid location or date.429 Too Many Requests: Rate limit exceeded.503 Service Unavailable: Service not available.
Example request:
curl -X GET "http://localhost:8080/api/v1/weather?location=Tampere&date=2025-08-14"- 400 Bad Request: When the request to the weather API is malformed.
- 401 Unauthorized (invalid or missing token)
- 429 Too Many Requests: When the request rate limit is exceeded.
- 503 Service Unavailable: When the weather API or cache is not available.
- The application uses Bucket4j for rate limiting. The default configuration allows 30 requests per minute.
- Add OpenAPI doc
- Implement /locations to show user's saved locations after login
- Implement refresh token
- Add testcontainers-based integration tests