Skip to content

Repository files navigation

🌍 GeoLocateAPI

Unified, free geolocation service built with Java 17 + Spring Boot + Clean Architecture.

Java Spring Boot Gradle Tests CI


Purpose

GeoLocateAPI provides a simple, reliable and fully free way to obtain geolocation data without relying on commercial APIs or paid subscriptions.

It exposes a clean REST interface for three essential operations:

  • IP β†’ Location
  • Coordinates β†’ City/Country
  • City Name β†’ Coordinates

The service acts as a unified layer over public, open-data providers (ip-api, OpenStreetMap/Nominatim, Open-Meteo), avoiding the friction of API keys, quotas and billing constraints.

The project is intentionally stateless, lightweight and easy to integrate, suitable for backend systems, mobile apps, internal tooling, analytics or prototyping.


Features

  • IP β†’ Location lookup
  • Coordinates β†’ Reverse geocoding
  • City β†’ Coordinates search
  • Unified GeoLocationData domain model
  • Clean Architecture
  • Hexagonal provider integration
  • Global exception handling
  • WireMock integration tests
  • MockMvc controller tests
  • Auto-generated Swagger/OpenAPI documentation
  • Per-endpoint rate limiting (Bucket4j) with standard rate-limit headers
  • In-memory response caching (Caffeine) with per-endpoint TTL
  • Provider fallback chains for IP lookup and reverse geocoding
  • Request validation (IP format, city length, latitude/longitude ranges)

Endpoints

Search by IP

GET /api/v1/geo/ip/{ip}

Example:

curl http://localhost:8080/api/v1/geo/ip/8.8.8.8

Reverse Geocoding

GET /api/v1/geo/coordinates?lat=40.0&lon=-8.0

Example:

curl http://localhost:8080/api/v1/geo/coordinates?lat=40.0&lon=-8.0

Search by City Name

GET /api/v1/geo/city/{name}

Example:

curl http://localhost:8080/api/v1/geo/city/Lisbon

Rate Limiting

Each endpoint is protected by per-client rate limits (Bucket4j):

Tier Limit Endpoints
IP_LOOKUP 30 req/minute GET /api/v1/geo/ip/{ip}
GEO_SEARCH 60 req/minute /coordinates, /city/{name}

Every response includes:

  • X-RateLimit-Limit
  • X-RateLimit-Remaining

When the limit is exceeded, the API responds with 429 Too Many Requests, a Retry-After header (seconds), and:

{ "error": "Too Many Requests", "retryAfter": 12 }

Clients are identified by the first X-Forwarded-For entry, falling back to the remote address.


Caching

Responses are cached in-memory (Caffeine) to reduce calls to upstream providers:

Cache TTL Max entries
geo-ip 24 hours 500
geo-coordinates 7 days 500
geo-city 7 days 500

Each response includes a cached boolean indicating whether the result came from cache:

{ "ip": "8.8.8.8", "city": "Mountain View", "...": "...", "cached": true }

Provider Fallback

To improve reliability, the API automatically retries with a secondary provider when the primary one is unavailable:

Operation Primary Fallback
IP β†’ Location ip-api.com ipinfo.io
Coordinates β†’ City OSM / Nominatim BigDataCloud
City β†’ Coordinates Open-Meteo β€” (none)

Architecture

Clean + Hexagonal Layout

src/
 β”œβ”€ domain/
 β”œβ”€ application/
 β”œβ”€ infrastructure/
 └─ presentation/

Architecture Diagram

Rendered SVG: architecture.svg

Source (PlantUML): architecture.puml


Setup

1. Clone the repository

git clone https://github.com/MarkADom/GeoLocateAPI.git
cd GeoLocateAPI

2. Run the application

./gradlew bootRun

3. Swagger / OpenAPI

Once the app is running:

  • Swagger UI: http://localhost:8080/swagger-ui/index.html
  • OpenAPI JSON: /v3/api-docs

Tests

./gradlew test

Future Improvements

  • API key authentication
  • Test coverage badge
  • Dockerfile (optional)
  • Persistent caching (Redis) for multi-instance deployments

Releases

GeoLocateAPI follows a simple and clean release flow:

  • main β†’ stable, production-ready versions
  • develop β†’ upcoming improvements and planned features

Latest Release

v1.1.0 β€” Resilience & Performance Update

Includes:

  • GitHub Actions CI pipeline (build + test on PRs)
  • Per-endpoint rate limiting (Bucket4j) with rate-limit headers
  • Provider fallback chains for IP lookup and reverse geocoding
  • In-memory response caching (Caffeine) with per-endpoint TTL
  • Request validation (IP format, city length, latitude/longitude ranges)

Previous Release

v1.0.0 β€” Initial Stable Release

Includes:

  • Core geolocation features (IP lookup, reverse geocoding, city search)
  • Clean Architecture + Hexagonal structure
  • Swagger/OpenAPI documentation
  • WireMock + MockMvc test suite
  • Architecture diagrams (PlantUML + SVG)
  • MIT License

πŸ‘‰ View all releases:
https://github.com/MarkADom/GeoLocateAPI/releases


Roadmap

The core of GeoLocateAPI is complete. Contributions are welcome.


About This Project

This service was originally built as part of my backend engineering portfolio, focusing on clean architecture, external API integration, structured testing and maintainability.


Author

Developed by Marco Domingues. Focused on clean, testable backend services that are easy to understand, extend and deploy.


License

This project is distributed under the MIT License.
See the LICENSE file for details.

About

Lightweight geolocation REST API built with Java 17, Spring Boot and Clean Architecture. Features rate limiting (Bucket4j), provider fallback chains, in-memory caching (Caffeine) and a full CI/CD pipeline.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages