Skip to content

Simple REST service that allows people to fetch the city/state/country location of a given IP address. Alternative project that uses Spring WebFlux.

Notifications You must be signed in to change notification settings

LuizParo/ip-geolocation-reactive

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Alternative project for ip-geolocation that uses Spring WebFlux instead of Spring MVC.

Table of Contents

About

Service responsible for fetching the city/state/country of a given IP address. When the IP is absent, the external IP of the machine this service is hosted on will be used instead.

The datasource used at this project is the GeoIP2, provided by MaxMind. It also uses Redis to cache the location associated with the IPs, in order to avoid unnecessary calls to the underlying GeoIP2 data store when the same IP is fetched more than once.

Requirements

  • Java 11+
  • Redis running locally on localhost listening to the port 6379 (can be easily run with Docker, check below how to do this).

Setup and running

Installing and Running locally

In order to get started, clone this repository into a directory of choice and run the following commands in it:

# setup redis
docker run --rm -p 6379:6379 --name ip-geolocation-redis -d redis

# compiles the code and generate the executable JAR
./mvnw clean package

# runs the application on port 8080
java -jar target/geolocation-1.0.0.jar

Running with Docker

The easiest way of running the application is by using Docker. Inside the project directory, run the following command to spin up the application:

docker-compose up

Running the tests

This application contains both unit and integration tests. In order to run them, execute the following command inside the project directory:

./mvnw clean test

General information

Application usage

In order to use the application, make sure it's running on port 8080. The root endpoint exposed is geolocation/ips, with the following specialized paths:

GET geolocation/ips/city?ip=${optionalIpAddress} - Getting the City/State of a given IP address:

In order to get the city/state location of an IP address, just call the geolocation/ips/city endpoint with the ip query parameter, like the following:

curl --location --request GET 'http://localhost:8080/geolocation/ips/city?ip=217.138.219.147' \
     --header 'Accept: application/json' \
     | json_pp

The response:

{
  "city": {
    "name": "Milan",
    "geoNameId": 3173435
  },
  "state": {
    "name": "Milan",
    "geoNameId": 3173434,
    "isoCode": "MI"
  }
}

In case the ip query parameter is absent, the external IP from the host machine will be used instead:

curl --location --request GET 'http://localhost:8080/geolocation/ips/city' \
     --header 'Accept: application/json' \
     | json_pp

The response:

{
   "city" : {
      "name" : "Montreal",
      "geoNameId" : 6077243
   },
   "state" : {
      "name" : "Quebec",
      "geoNameId" : 6115047,
      "isoCode" : "QC"
   }
}

GET geolocation/ips/country?ip=${optionalIpAddress} - Getting the Country of a given IP address:

In order to get the country of an IP address, just call the geolocation/ips/city endpoint with the ip query parameter, like the following:

curl --location --request GET 'http://localhost:8080/geolocation/ips/country?ip=217.138.219.147' \
     --header 'Accept: application/json' \
     | json_pp

The response:

{
    "country": {
        "name": "Italy",
        "geoNameId": 3175395,
        "isoCode": "IT",
        "inEuropeanUnion": true
    }
}

In case the ip query parameter is absent, the external IP from the host machine will be used instead:

curl --location --request GET 'http://localhost:8080/geolocation/ips/country' \
     --header 'Accept: application/json' \
     | json_pp

The response:

{
   "country" : {
      "isoCode" : "CA",
      "geoNameId" : 6251999,
      "inEuropeanUnion" : false,
      "name" : "Canada"
   }
}

Overall architecture

This application follows the basic layered architecture, having the following flow of interactions between them:

controller -> api -> service -> repository

The code is mainly divided in the following packages:

controller

Represents the controller layer and is the entrypoint of the application. The endpoints and DTOs are declared in this package. The controller calls are forward to the api layer for processing.

api

Represents the api layer of the application. It contains classes that validate/convert incoming DTOs into domain objects, and coordinates subsequent calls to services. It should contain as least responsibility as possible, mostly forwarding calls to another classes/services.

domain

Contains the domain objects that are used in the service layer of the application. They are immutable.

service

Represents the service layer of the application. Most of the application business logic is contained in this package. It is also responsible for forwarding calls to the repository layer to fetch the IP address location.

repository

Represents the repository layer of the application. It contains repository interfaces to get the city/state/country of an IP address, which uses the GeoIP2 database and Redis for caching.

About

Simple REST service that allows people to fetch the city/state/country location of a given IP address. Alternative project that uses Spring WebFlux.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published