Codementor Events

Integrating Additional APIs in your Weather App

Published Jun 28, 2021Last updated Dec 24, 2021
Integrating Additional APIs in your Weather App

Developing an application sometimes involves working with multiple APIs. In this scenario, the best approach in terms of project structure and code maintainability is to create a wrapper for each API you consume and call the methods exposed by them, when needed.

To better demonstrate and understand this, in this article, we will make a small demo application for the weather.

Let's start with the following example:

const app = require("express")();

app.get("/weather", (req, res) => {
  res.send('weather);
});

app.get("/air-quality", (req, res) => {
  res.send('air-quality);
});

app.listen(3000, () => {
  console.log("server is up at port 3000");
});

We have a back-end application, a web server, for weather monitoring and we are interested in both regular weather data such as temperature, humidity, wind speed and so on, but also air quality data.

When it comes to having multiple APIs integrated into the same application, this usually comes from the fact that one API does not provide all the data you need or that you are not satisfied with some of the data that it provides and you want to use a replacement just for that portion of information.

The same goes for our demo application: Let's imagine that we have a weather API that we really fancy and we want to use, but it doesn't provide air quality data. So, for this part, we will use another API.

To keep the article short, we will only create a wrapper for one of these two data layers---because the other will be the same. Not many APIs provide information about air quality, so let's focus on this wrapper.

Step I - The API

The first step would be to choose an API and see how it can be used. For this demo application let's go with the Tomorrow.io Air Quality API. Like any other API, it has a secret key-based communication model. That is, each consumer has their own private API key that they use to submit requests.

UnnmBRr0.png

The air quality data can be obtained through a GET request to their all-in-one route. Air quality is just one data layer that they provide beside many others, but they all use the same route, so it's very easy to use.

The base URL looks like this:

https://data.tomorrow.io/v4/timelines

Based on the documentation at this URL we need to add the following query parameters:

  • location: the geographical coordinates for which you want to obtain the data
  • apikey: your secret API Key
  • timesteps: the time frame of the data you want to acquire (minutely, hourly, daily and so on)
  • fields: an array with the fields you want to see, in our case, for air quality, exactly the ones from here

Step II - The Wrapper

Because I want to keep this as general as possible, I'll not get into any programming language-specific details and we will focus on the main aspect so that you can reproduce it in your own projects, regardless of the programming language used.

What's worth mentioning here is that in a new file, air-quality.js, I created a new class based on the singleton pattern.

One way to do this in JavaScript can be:

const fetch = require("node-fetch");

class Class {
  #CC_KEY = "your_api_key";
}

const AirQualityApi = new Class();
Object.freeze(AirQualityApi);

module.exports = { AirQualityApi };

node-fetch is just the library that we will use to send the GET request and #CC_KEY is a private variable that stores the API Key we will use to communicate with Tomorrow.io.

Step III - Acquire the Data

The task of this wrapper is quite simple---for a certain **latitude **and longitude, request and return some information about air quality.

This can be achieved by creating a public method with the following code:

  async getAirQuality(lat, lon) {
    const url = `https://data.tomorrow.io/v4/timelines?location=${lat},${lon}&apikey=${
      this.#CC_KEY
    }&fields=particulateMatter10&fields=particulateMatter25&timesteps=1m`;

    const fetchRes = await fetch(url);
    const json = await fetchRes.json();

    const { values } = json.data.timelines[0].intervals[0];
    return values;
  }

The URL constant is exactly the same URL that we discussed above---as fields specified particulateMatter10 and particulateMatter25. They represent the concentration of atmospheric particulate matter (PM) that has a diameter of fewer than 10 and 2.5 micrometers.

The raw response of Tomorrow.io API is the following JSON object:

ifw9PNwE.png

This exact value was captured in constant JSON and represents the data per minute. Therefore, to get the current value, we need to access data.timelines[0].intervals[0].values.

Step IV - Put Everything Together

Now if we put everything together, we'll have the following project structure (NodeJS based):

C-g_ZV2g.png

And the server's code will be the following:

const app = require("express")();

const { AirQualityApi } = require("./air-quality");
const { WeatherDataApi } = require("./weather-data");

app.get("/weather", async (req, res) => {
  const { lat, lon } = req.query;
  const data = await WeatherDataApi.getWeatherData(lat, lon);

  res.json(data);
});

app.get("/air-quality", async (req, res) => {
  const { lat, lon } = req.query;
  const data = await AirQualityApi.getAirQuality(lat, lon);
  res.json(data);
});

app.listen(3000, () => {
  console.log("server is up at port 3000");
});

We only wrote the code for the AirQualityApi class, but the same goes for WeatherDataApi, just that it will have another data provider.

If we start this application and send the following GET request http://localhost:3000/air-quality?lat=41.3851&lon=2.1734 we will get pm10 and pm25 data for location with tthe coordinates 41.3851 ° N 2.1734 ° E.

RKw-nb4M.png

Conclusion

Integrating additional APIs into your application is not a difficult process. All you have to do is create modularization. By separating the code into separate components it will be much easier to maintain.

Cover Photo by ROBIN WORRALL on Unsplash

Discover and read more posts from Josh Robins
get started
post commentsBe the first to share your opinion
Show more replies