IP geolocation is a highly beneficial technology for obtaining geographic data based on an IP address. Most startups use MaxMind's free dataset to acquire geolocation information from an IP address.

  1. First, you need to download the dataset from Maxmind website. Sign up here https://dev.maxmind.com/geoip/geolite2-free-geolocation-data and download the GeoLite2 City .mmdb dataset.

  2. Now make a folder in the project app/datasets and save the GeoLite2 City .mmdb file there.

  3. Install the maxmind package.

terminal

Copy
npm install maxmind
  1. Open server.js file and add two lines in this file.

JavaScript

Copy
// server.js const geoRoutes = require('./app/routes/geoRoutes'); app.use('/geo', geoRoutes);
  1. Create a route file in the app/routes directory named geoRoutes.js

JavaScript

Copy
// app/routes/geoRoutes.js const express = require('express'); const router = express.Router(); const geoController = require('../controllers/geoController'); router.get('/data', geoController.geoData); module.exports = router;
  1. Create a controller file in the app/controllers directory named geoController.js

JavaScript

Copy
// app/controllers/geoController.js const { responseList } = require('../errors/responseList'); const maxmind = require('maxmind'); const path = require('path'); // Path to your GeoLite2-City.mmdb file const dbPath = path.join(__dirname, '../datasets/GeoLite2-City.mmdb'); // Open the MaxMind database outside the handler to avoid reopening it on every request let lookup; maxmind .open(dbPath) .then((geoLookup) => { lookup = geoLookup; }) .catch((err) => { console.error('Error opening MaxMind database:', err); }); exports.geoData = async (req, res) => { try { const { ip } = req.query; if (!ip) { return res .status(400) .send(responseList(400, 'IP address is required')); } // Query the database for the given IP const geoData = lookup.get(ip); if (!geoData) { return res .status(400) .send(responseList(400, 'Geolocation data not found')); } res.status(200).send(geoData); } catch (err) { res.status(500).send(responseList(500)); } };

Now your API endpoint is ready and can test like this.

terminal

Copy
http://localhost:3001/geo/data?ip=123.45.6.78

This will be the result for that IP.

JavaScript

Copy
{ "continent": { "code": "AS", "geoname_id": 6255147, "names": { "de": "Asien", "en": "Asia", "es": "Asia", "fr": "Asie", "ja": "アジア", "pt-BR": "Ásia", "ru": "Азия", "zh-CN": "亚洲" } }, "country": { "geoname_id": 1835841, "iso_code": "KR", "names": { "de": "Südkorea", "en": "South Korea", "es": "Corea del Sur", "fr": "Corée du Sud", "ja": "大韓民国", "pt-BR": "Coreia do Sul", "ru": "Республика Корея", "zh-CN": "韩国" } }, "location": { "accuracy_radius": 200, "latitude": 37.5112, "longitude": 126.9741, "time_zone": "Asia/Seoul" }, "registered_country": { "geoname_id": 1835841, "iso_code": "KR", "names": { "de": "Südkorea", "en": "South Korea", "es": "Corea del Sur", "fr": "Corée du Sud", "ja": "大韓民国", "pt-BR": "Coreia do Sul", "ru": "Республика Корея", "zh-CN": "韩国" } } }

And you can deploy this on DigitalOcean, Render, & Also on Glitch.