Published on

Creating a weather app with IP geolocation API in Node.js

Authors
  • Shantanu Shukla
    Name
    Shantanu Shukla
    Title
    External Contributor
    Social media profiles

In this blog, we will learn how to integrate two APIs in a single project and make them talk to each other. We will create a Node.js app that will use an IP geolocation API and a weather API. I believe many developers created a weather app as one of their learning projects. Today, we can move a bit forward and add another API to make the weather app smarter.

In a typical weather app, you’d need to enter your location, but in our project, we will find out the current location using an IP geolocation API.

Below we have a basic structure of our app. We can see that there are three important steps involved:

  1. Getting device’s IP address
  2. Calling IP geolocation API with the IP address as a parameter and saving the returned object
  3. Calling weather API with state and city as parameters and outputting the result to the user

Setting up the server

We are going to use Node.js and Express to create our app.

mkdir geo-wea
cd geo-wea
npm init -y
npm i express

We will use modern ES Modules. For Node.js to handle them correctly, go to package.json file and add "type": "module". The result should look something like this:

{
  "name": "geo-wea",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.1"
  }
}

Create index.js file with the following code:

import express from 'express';

const app = express();
app.listen(3000, () => {
  console.log('Server listening on 3000');
});

Now to check if everything works, run the application:

node index.js

Extracting device's IP address

Every request a device sends to a server will always have an IP address of the device.

Now we need to read an IP address of the device connecting to our application. Express can read it from the incoming connection. Typically, our application will run behind a reverse proxy, which will pass the original IP address in HTTP headers. Express won’t read this header by default, but you can instruct it to trust the IP address passed in headers from the proxy:

app.set('trust proxy', true);

To learn more, check Public vs. Private IP Address: What's the Difference.

We can read the IP address from the ip property of the incoming request (req). Replace index.js with the following code:

import express from 'express';
const app = express();
app.set('trust proxy', true);

app.get('/', async (req, res) => {
  const ip = req.ip;
  res.send(ip);
});

app.listen(3000, () => {
  console.log('Server listening on 3000');
});

Now, when you visit your application running locally or on CodeSandbox, you should see your IP address.

Note: I am using CodeSandbox for this example because if I run the server on my PC, it would see me connecting from localhost or local IP address.

Installing Superface SDK

I am going to use Superface for API integration as it makes the integration super easy. Since we will use two APIs in this project, normally I’d have to go through two different API docs, but with the mighty power of Superface, I don’t need to. Learn one to conquer all.

First, install Superface OneSDK in your app:

npm i @superfaceai/one-sdk@2

We will ue the following use cases from the Superface catalog: IP geolocation lookup and Current Weather In City.

IP geolocation API

This allows us to identify the country, state, and city based on the IP address of your device. To find out more about IP geolocation, check my previous article.

Now we have to pick a provider to use. I will use ipdata. Create an account on ipdata.co to get your API key.

Back in Superface, select ipdata provider, copy and paste the code from the example into your index.js file. Replace <your apikey from ipdata> with the API key you got from ipdata and the public IP address you into the ipAddress property.

Here is the resulting code:

import express from 'express';
import { SuperfaceClient } from '@superfaceai/one-sdk';

const app = express();
app.set('trust proxy', true);

const sdk = new SuperfaceClient();

async function run(ip) {
  // Load the profile
  const profile = await sdk.getProfile('address/ip-geolocation@1.0.1');

  // Use the profile
  const result = await profile.getUseCase('IpGeolocation').perform(
    {
      ipAddress: ip,
    },
    {
      provider: 'ipdata',
      security: {
        apikey: {
          apikey: '<your apikey from ipdata>',
        },
      },
    }
  );

  // Handle the result
  try {
    const data = result.unwrap();
    return data;
  } catch (error) {
    console.error(error);
  }
}

app.get('/', async (req, res) => {
  res.send(await run(req.ip));
});

app.listen(3000, () => {
  console.log('SERVER RUNNING AT PORT 3000');
});

Now just run your app with node index.js, visit localhost:3000, and you should see a result:

geo_code.png

Weather API

Moving on to the third step: calling the weather API with the data returned by IP geolocation API. This API will return to us the current weather in the city we provide. Find Get Current Weather In City in Superface catalog and choose a provider. For this tutorial, I will use openweathermap.

Create an account on OpenWeatherMap.

q1.png

Same as before, copy and paste the code from the example. Replace <your apikey from openweathermap> with the API key you got from OpenWeatherMap and pass in the city you got from the call to Geocoding API. Rename the run function, to something more descriptive. Here’s the resulting code:

import express from 'express';
import { SuperfaceClient } from '@superfaceai/one-sdk';

const app = express();
app.set('trust proxy', true);

const sdk = new SuperfaceClient();

async function findCity(ip) {
  // Load the profile
  const profile = await sdk.getProfile('address/ip-geolocation@1.0.1');

  // Use the profile
  const result = await profile.getUseCase('IpGeolocation').perform(
    {
      ipAddress: ip,
    },
    {
      provider: 'ipdata',
      security: {
        apikey: {
          apikey: '9a511b6fc8334e1852cfbbd4ff3f1af3c42ed6abc75e96a1648b969a',
        },
      },
    }
  );

  // Handle the result
  try {
    const data = result.unwrap();
    return data;
  } catch (error) {
    console.error(error);
  }
}

async function weather(city) {
  // Load the profile
  const profile = await sdk.getProfile('weather/current-city@1.0.3');

  // Use the profile
  const result = await profile.getUseCase('GetCurrentWeatherInCity').perform(
    {
      city: city,
      units: 'C',
    },
    {
      provider: 'openweathermap',
      security: {
        apikey: {
          apikey: '9a7c7994ccda87a3f8bb2767d5ca48db',
        },
      },
    }
  );

  // Handle the result
  try {
    const data = result.unwrap();
    return data;
  } catch (error) {
    console.error(error);
  }
}

app.get('/', async (req, res) => {
  try {
    let city = await findCity(req.ip);
    res.send(await weather(city.addressLocality));
  } catch (error) {
    console.log(error);
  }
});

app.listen(3000, () => {
  console.log('SERVER RUNNING AT PORT 3000');
});

Now run your app with node index.js you should see the result:

You can find the final result on CodeSandbox.

Automate the impossible.
Superface. The LLM-powered automation agent that connects to all your systems.

Try it now