YG
Projects
Projects

Backend

Weather API

2026

Location-Aware Weather Backend

Maintained

A Spring Boot weather service that resolves approximate client location, retrieves current conditions and forecasts from external providers, and exposes a frontend-friendly REST API with caching and structured error handling.

Java, Spring Boot, Spring MVC, REST APIs, Caffeine, External APIs, OpenAPI, Docker, JUnit, GitHub Actions, Google Cloud Run


Weather API

A production-minded Spring Boot API for a weather UI. It resolves the caller’s approximate location from their network address, retrieves current conditions and a six-day forecast, and returns a frontend-friendly JSON response.

Highlights

Architecture

WeatherController obtains the address exposed by Spring’s forwarded-header support and delegates to WeatherService. The service uses GeolocationService and the two HTTP clients, validates provider payloads, then maps provider DTOs to public API DTOs. Successful OpenWeatherMap payloads are cached locally by rounded coordinates. Entries expire after 10 minutes and are limited to 1,000.

Requirements and local setup

The application uses Spring Boot 4.0.5, Java 21, Maven, Spring MVC, Spring Cache/Caffeine, and springdoc-openapi 3.0.2.

cp .env.example .env
set -a; source .env; set +a
./mvnw spring-boot:run
Variable Required Description
OWM_API_KEY Yes OpenWeatherMap One Call API 3.0 key

OWM_API_KEY is intentionally not stored in source control. .env is ignored by Git and only helps export it locally. Local loopback requests do not represent a public location; use a real client/proxy address when manually exercising geolocation.

API documentation

All public endpoints are GET endpoints under /api/v1.

Endpoint Description
/api/v1/mini-weather Current temperature and condition for the caller’s approximate location
/api/v1/full-weather Current details plus six forecast days for the caller’s approximate location
curl http://localhost:8080/api/v1/mini-weather
{"description":"Clear Sky","temperature":28.5}

Error responses have one consistent shape:

{"timestamp":"2026-08-26T15:00:00Z","status":504,"error":"Upstream timeout","message":"The weather provider did not respond in time.","path":"/api/v1/mini-weather"}
Status Meaning
200 Weather response returned
400 Missing or invalid client address
502 A provider returned an invalid response or failed
504 A provider did not respond before the configured timeout
500 Unexpected server error

Tests

./mvnw verify

Tests mock service/provider boundaries and require neither an API key nor network access.

Docker

docker build -t weather-api .
docker run --rm -p 8080:8080 -e OWM_API_KEY=your-key weather-api

The image runs as a non-root spring user. Its build stage executes the test suite before producing the runtime image.

CI and deployment

GitHub Actions runs ./mvnw -B verify, builds the image, and pushes it to the public Docker Hub repository <DOCKERHUB_USERNAME>/weather-api before deploying it to Cloud Run. The workflow requires GCP_PROJECT_ID, DOCKERHUB_USERNAME, DOCKERHUB_TOKEN, CLOUD_RUN_SERVICE_NAME, WIF_PROVIDER, WIF_SERVICE_ACCOUNT, and OWM_API_KEY GitHub secrets. DOCKERHUB_TOKEN should be a Docker Hub access token with write access to the repository; do not use an account password. Deployment to Cloud Run continues to use Workload Identity Federation, with GCP_PROJECT_ID explicitly selecting the target project.

Geolocation is approximate and can reflect VPN or ISP routing. CORS defaults target the existing frontend and local development; adjust them for another frontend domain.

GitHubGitLabLinkedIn[email protected]