Your own GeoIP service 1/2: Maxmind GeoIP + AWS SAM

My own endpoint which will receive an IP as query parameter and it will return location info such as country and city

Screenshot of the Wall of Wonder.
Tiempo de lectura 3 minutos


This is not a start-from-subzero tutorial, so you will need a few things installed and working on your machine before starting this first post:

There so much literature about using GeoIP third party services, but if you really like to play and test a DIY GeoIP endpoint to use in your projects, follow me across two posts and let's check how to do it.

Let's be clear about the final goal: "My own endpoint which will receive an IP as query parameter and it will return location info such as country and city". To accomplish this goal we will make use of the following technologies/services:


First of all, Maxmind ( ) offers us a group of free GeoIP (capped) databases to play with. Follow instructions in the URL above and download "GeoLite2 City":

Maxmind download

Maxmind file

Locate the file "GeoLite2-City.mmdb" to be able to use it later.

Now let's check the usage for NodeJS of their APIs at, do not worry, we will spare a few lines of code in few moments.

AWS Serverless ApplicationManager (SAM)

SAM allows us to build and deploy serverless applications with little effort. Though SAM is oriented towards offering full REST capabilities in order to build a whole application, we will only use it to manage, invoke and deploy a Lambda function.

Since installing SAM and getting started with it is out of scope for this post, you may follow the official doc to do that

Whenever you have SAM working in your machine, follow these steps.

  1. Navigate to your dev playground folder and exec sam init . Setup the project like in the folowing screenshot:SAM-cli setup maxmind

  2. Exec cd geoIPNode

  3. Exec sam local invoke and this will execute the default from template.yml so you should see the following output(Note: you need Docker in your machine):Alt Text

  4. We already executed a Lambda function in our machine successfully, that is good, really good.

Maxmind again

Let's go back to and check the NodeJS code from their page. We will use the Buffer example:

const fs = require('fs');
const Reader = require('@maxmind/geoip2-node').Reader;
// Typescript:
// import { Reader } from '@maxmind/geoip2-node';

const dbBuffer = fs.readFileSync('/usr/local/city-database.mmdb');
const reader = Reader.openBuffer(dbBuffer);


Do you remember where the *.mmdb file is? It is time to put it inside the project folder in order to get a folder structure like this one:

Alt Text

Now add the replace the initial code for this (replace for you IP):

const fs = require('fs');
const Reader = require('@maxmind/geoip2-node').Reader;
 exports.helloFromLambdaHandler = async () => {
    let response={};

    const dbBuffer = fs.readFileSync('GeoLite2-City.mmdb');
    const reader = Reader.openBuffer(dbBuffer);

    try {
        // const ret = await axios(url);
        response = {
            'statusCode': 200,
            'body': JSON.stringify({
                message: 'hello world',
    } catch (err) {
        return err;

    return response

Note: do not forget to install @maxmind/geoip2-node using Yarn or NPM, for example:

npm install @maxmind/geoip2-node

An exec again sam local invoke :

Alt Text

That was easy.

The second part is already published.

Compartir en: