How to Build a NodeJS Wrapper for a Weather API

Stan Georgian
ITNEXT
Published in
5 min readApr 8, 2021

--

Photo by Mael BALLAND on Unsplash

If you clicked on this article, you probably want to integrate a weather API into your application. Maybe this is a requirement and your application is heavily oriented around weather data, or maybe just an enhancement. The idea is that you need to acquire some weather information and do something with them.

Most APIs use REST, GET, and POST calls to communicate with clients and send required data. Often, you have to create a long URL for a GET request or a complex POST body with some other headers as well. Rather than writing these calls every time you want to get weather data, you could wrap these GET or POST calls in some easy-to-use functions and have them available through the entire project(s).

After all, DRY is a core principle of programming and we should apply it here as well.

In this article, we’ll see one way in which we can build a small wrapper around a weather API.

The main idea is to encapsulate the reaping code and expose its functionality through a function, method, or property.

As a programming paradigm, we’ll use OOP and encapsulate the code in a class.

The Code

For this article, I chose to use the Tomorrow.io Weather API. This is a free-to-use API that offers more than one data layer. You can use it to acquire data about air quality, pollen fire risk, and more. The documentation is also very comprehensive and easy to digest with many resources and guides for developers.

On top of that, with the latest API update, all endpoints were collapsed in just a single data call, therefore introducing all-in-one endpoints that accept any weather query makes the integration part way easier.

If you have a different weather API you want to you, you can still adapt the code in this article and apply the relevant patterns.

Step 1: Project Setup

We are building a NodeJS wrapper for the back-end of our application. The project setup is quite straightforward.

Open a new command line and in your desired folder run the command npm init -y followed by the command npm i node-fetch. This will create the file package.json and install the module node-fetch, which is a lightweight module that brings window.fetch to Node.js.

To complete this setup create an index.js file and import the node-fetch module.

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

Step 2: The Documentation

To build a wrapper for an API, we first need to communicate with the API. In this situation, the API’s documentation is our best friend. This is the URL from the Tomorrow.io documentation:

https://data.tomorrow.io/v4/timelines?location=LAT%2CLONG&fields=FIELD_NAME&timesteps=1m&apikey=API_KEY

To get weather data from this provider, we’ll need to supply:

  • the latitude and longitude of our desired location
  • our API_KEY
  • the timesteps: 1m for real-time, 1h for hourly, and 1d for daily data.

The fields parameter will be an array with the fields for which we what to get data for. These values are available under Data Layers.

The API_KEY can be acquired by creating a free account on their platform. They provide a free API key to use with a limit of 1000 calls / per day.

Starting with this information, let’s say that we want to get the temperature, humidity, and the probability of precipitation for Barcelona in real-time. We’ll need to make a GET request to the following URL:

https://data.tomorrow.io/v4/timelines?location=41.3851%2C2.1734&fields=temperature&fields=humidity&fields=precipitationProbability&timesteps=1m&apikey=API_KEY

To test this, you can replace API_KEY with your own secret key and then paste this URL in a new tab and you should see the following output.

By default, the values will be in the International System of Units. if you want to retrieve the data in the United States customary units, then all you have to add the parameter &units=imperial.

Step 3: The Wrapper

Now that we know how to compose the URL, we can start coding.

We’ll start by defining our class and constructor.

The constructor will receive as arguments the API_KEY and the coordinates of the desired location and will store them as private fields.

Step 4: Get the data

As we previously mentioned, in the latest Tomorrow.io update all the endpoints were collapsed in just one endpoint that includes all the data we need, therefore we need to create one general method that will receive the fields that we want to acquire as parameters, and the time steps: realtime, daily or hourly.

Because node-fetch is a light-weight wrapper for window.fetch, it doesn’t provide a way to build a complex URL with query parameters. Thus, to make things easier I wrote a simple function that will build the URL for us:

Remember that our test URL was:

https://data.tomorrow.io/v4/timelines?location=41.3851%2C2.1734&fields=temperature&fields=humidity&fields=precipitationProbability&timesteps=1m&apikey=API_KEY

We can use this helper function queryBuilder() to build this URL. The function call would look like this:

const url = queryBuilder("https://data.tomorrow.io/v4/timelines", {
location: '41.3851%2C2.1734',
apikey: API_KEY,
fields:['temperature','humidity','precipitationProbability']
timesteps:'1m',
});

Now, all we have to do is to create a general method that will be used to acquire the data we want by supplying the fields array and timesteps as arguments.

The purpose of this function is to compute the correct URL, send the request to Tomorrow.io, and return the response with no alteration.

Step 5: How to Use it

To use this simple wrapper, we need to instantiate a new object using the class that we just created and call getWeatherData():

We can also include fields from other data layers. For example, if we want to see what is the temperature, humidity but also the air quality, we can update the fields array with the values from the Air Quality data layer:

["temperature", "humidity", "particulateMatter25","particulateMatter10"]

And that’s it! Based on the API, you use you can extend this simple wrapper even further.

In the current state, because latitude and longitude are sent as arguments in the constructor, you need to create a new instance for each location you want to monitor. If you want to monitor for multiple locations and don’t want to create a new object for each location, then you could create a static method that will receive in the same way the fields and the timesteps, but also the latitude, longitude and the apikey.

--

--