/nearest-store

Get nearest points based on coordinates using haversine formula with latitude and longitude over JPA

Primary LanguageJavaApache License 2.0Apache-2.0

Nearest Store JPA

Quality Gate Status Maintainability Rating Reliability Rating Security Rating Technical Debt Coverage

This project provides one endpoint to get the nearest stores based on geographic coordinates in WSG84 decimal degrees.

To calculate the distance between provided coordinates and stores, is used the haversine formula in a JPA implementation.

As JPA is very portable, it's possible to run this query without complications in several databases of your choice. As for an example and portability, a H2 database is loaded in memory, as reference to this implementation.

Technologies

Prerequisites

  • JDK 17
  • Maven 3.6 (or newer)
  • Port 8080 available (for Tomcat serve API and static content)

Compiling and Running

  1. Clone this repository:

git clone https://github.com/marcelorodrigo/nearest-store.git

  1. Build using Maven

mvnw clean install

  1. Execute generated project

java -jar target/nearest-store-1.0.0.jar

  1. You can access static content via:

http://127.0.0.1:8080/

API Usage

OpenApi v3 documentation is available. You can try it online

http://127.0.0.1:8080/store/?latitude={double}&longitude={double}

This endpoint provides the 5 closes stores on the database, ordered by distance, to the provided latitude and longitude coordinates.
A response should look like:

"content": [
    {
         "uuid": "afYAKYx4XKmYBBBFJVw0JT95B",
         "addressName": "Best Mega Store",
         "street": "Ros Van Dalen",
         "street2": "5",
         "street3": "",
         "city": "Best",
         "postalCode": "5684 MW",
         "complexNumber": "19724",
         "showWarningMessage": true,
         "latitude": 51.487243,
         "longitude": 5.044087,
         "todayOpen": "08:00",
         "locationType": "Supermarkt",
         "collectionPoint": true,
         "todayClose": "23:30"
    }
 ],
"pageable": {}

Paging

The endpoint has pagination capabilities via Query Params:

  • size for sizing page results (default 5)
  • page for page number. (default 0)

Versioning

This API is versioned using Media Type Versioning, so that you must include the desired version on Accept header:

Accept: application/vnd.neareststore.v1+json

Tests

Unit Tests and Controller Tests are included as part of the code, you can execute all tests by running this command on project root:

mvnw test

Coverage Report

After running tests on the command above, you can browse a Coverage Report generated by Jacoco on target/site/jacoco/index.html

Bonus

A really simple interface was built using Vue and OpenLayers + OpenStreetMap

http://127.0.0.1:8080/

Screenshot

Have fun navigating the globe and seeing the closest shops to you ☺️
ProTip: If you're not seeing stores close to you, try to navigate in The Netherlands

Improvements

  • Real database: as H2 it's a in-memory database, every startup it's necessary to run migrations and feed database. So using a real database it's a good idea.
  • Geospatial Database functions: as the idea here is to show how to solve the problem using haversine formula over JPA to compute the distance between two coordinates on the Earth, using geospatial database functions could speed up this computing process and turn it into less error prone.