Integrating Zomato’s Weather Union API in Spring Boot: A Step-by-Step Guide

Inzi
7 min readJul 28, 2024

--

Two months ago, Zomato revolutionized India’s weather monitoring landscape by launching WeatherUnion, India’s first crowd-supported weather infrastructure. This ambitious project, announced by the company’s founder, Deepinder Goyal on LinkedIn in May 2024, boasts the largest on-ground network of weather stations, with over 650 stations spread across 45+ cities and counting. For comparison, OpenWeather, one of the largest public domain APIs, uses only 371 cities globally for weather prediction as stated here, with a mere 11 cities in India. WeatherUnion’s comprehensive coverage, monitoring weather at the locality level, is going to be a game-changer.

The vision behind WeatherUnion is to make this rich data open source, unlocking numerous use cases for enterprises and research institutions. Since the launch, they have already scaled from 650 stations to 750 and now available in 60+ cities within a matter of 2 months. It won’t be wrong to say that this is the fastest growing network in India, highlighting its potential to provide accurate, localized weather data crucial for farmers, city planners, and everyday citizens.

Imagine the impact: farmers making informed decisions on irrigation and pest control, city dwellers better preparing for severe weather, and researchers predicting climate trends. WeatherUnion is not just a technological marvel but a vital tool for enhancing resilience and productivity across various sectors.

So, why not jump onto it? It’s our own homegrown innovation. Today, let’s learn how to use it.

Aim : To make a request to Weather Union API using Rest Template in Spring Boot.

Pre-requisites :

  1. Familiarity with Spring Boot Framework.
  2. Basic knowledge of RESTful APIs and HTTP.
  3. Any IDE — Eclipse, IntelliJ etc.

Step 1 : Getting the API access KEY

An API access key is a unique identifier used to authenticate and authorize clients making requests to an API, ensuring secure and controlled access. It helps track usage, manage permissions, and implement rate limits to prevent abuse.

A. Login to the Weather Union website using your email address.

B. Go to your profile section inside the top-right hamburger menu.

C. Onboard yourself if you have not already done so.

D. You can find your API Key in the “Your API access key” section as shown below. It also shows you that your limit of making API request is upto 1000.

Step 2 : Exploring API end points — Optional

This step can be skipped as you can just go through the documentation. But just for beginners in order to give you more clarity lets explore the endpoints.

There are two enpoints mentioned:

i. API for current weather data at a lat, long
ii. API for current weather data in a locality

Lets explore the first one where you need to pass the latitude and longitude of the place we want to access the weather. The list of latitude and longitudes are given here.

A. Open Postman.

B. Select Request Method as GET and then enter this URL to check weather at Colaba, Mumbai :

https://www.weatherunion.com/gw/weather/external/v0/get_weather_data?latitude=18.919405&longitude=72.824376

The params will automatically updated in this case.

C. In Postman, select Headers tab that is below the URL field. Specify the values as shown. No quotes required.

Key: x-zomato-api-key
Values: Your API key

D. Observe the response

Please note that the Response is JSON object. Within this JSON object, there is a key called "locality_weather_data" that contains another JSON object with all the values of your concern. This will become important in a minute.

Similarly for the second endpoint you will need to specify the locality Id of the target location, which you can find here.

Step 3 : Spring Boot application Generation

Go to this link and hit Generate.

OR

Head out to Spring Initializr (here) and create a Spring boot application with “Spring Web” and “Lombok” dependency and then hit Generate.

This will download your Project and Now you can open that in your respective IDE. I will be using IntelliJ for this Project.

Congratulations! for making it this far.

Step 4 : Creating a Controller

Inside com.inzi.WeatherUnionAPI create two packages named :
i. controller
ii. dto

Inside the controller package,
Create a class named as: WeatherUnionAPIController

Inside the dto package, Create two classes named as:
i. ApiResponse
ii. LocalityWeatherData

After all this your file structure will look like this:

Now you are all set.

Step 5 : Creating Rest Template Bean object

Go to your main function and add this code:

@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}

Make sure to import the respective classes.

Step 6 : Creating Data Transfer Objects (dtos)

A. Inside the ApiResponse, copy and paste this code:

package com.inzi.WeatherUnionAPI.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class ApiResponse {
private int status;
private String message;
private int device_type;

LocalityWeatherData locality_weather_data;

@Override
public String toString() {
return "Custom ApiResponse=\n{\n" +
"\t status=" + status +
",\n\t message='" + message + '\'' +
",\n\t deviceType= " + (device_type==1?"1 - Automated weather system":device_type==2?"5 2 - Rain gauge system":device_type) +
",\n\t localityWeatherData=" + locality_weather_data +
"\n}";
}
}

B. Inside the LocalityWeatherData, copy and paste this code:

package com.inzi.WeatherUnionAPI.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class LocalityWeatherData {

private float temperature;
private float humidity;
private float wind_speed;
private float wind_direction;
private float rain_intensity;
private float rain_accumulation;

@Override
public String toString() {
return "\n\t\t LocalityWeatherData {\n" +
"\t\t\t Temperature = " + temperature + "°C"+
",\n\t\t\t Humidity= " + humidity + "%"+
",\n\t\t\t Wind_speed= " + wind_speed + "m/s"+
",\n\t\t\t Wind_direction= " + wind_direction + "°"+
",\n\t\t\t Rain_intensity= " + rain_intensity + "mm/min"+
",\n\t\t\t Rain_accumulation= " + rain_accumulation + "mm today counting from 12 AM IST"+
"\n\t\t}";
}
}

Step 7 : Making a request to the API

For making a request to the API we will be using Rest template’s exchange method.

Also its a good practise to make the call from Service Layer, as per Spring MVC architecture. Just for easy of understanding and simplicity I have done it in controller itself.

Copy paste this code in the WeatherUnionAPIController:

package com.inzi.WeatherUnionAPI.controller;

import com.inzi.WeatherUnionAPI.dto.ApiResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

@CrossOrigin
@RestController
@RequestMapping(value = "api/weather")
public class WeatherUnionAPIController {
private final RestTemplate restTemplate;

@Value("${weatherunion.api.key}")
private String apiKey;

public WeatherUnionAPIController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}

@GetMapping(value = "/")
public ResponseEntity<String> fetchWeather(@RequestParam(defaultValue = "12.936225") float latitude,
@RequestParam(defaultValue = "77.665059") float longitude) {

String apiUrl = "https://www.weatherunion.com/gw/weather/external/v0/get_weather_data?latitude=" + latitude + "&longitude=" + longitude;

HttpHeaders headers = new HttpHeaders();
headers.set("x-zomato-api-key", apiKey);

HttpEntity<String> entity = new HttpEntity<>(headers);
//System.out.println(apiUrl);
//System.out.println(entity);

ResponseEntity<ApiResponse> response = restTemplate.exchange(
apiUrl, HttpMethod.GET, entity, ApiResponse.class);

//System.out.println(response.getBody());
System.out.println(restTemplate.exchange(
apiUrl, HttpMethod.GET, entity, ApiResponse.class));
if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
return new ResponseEntity<>(response.getBody().toString(), HttpStatus.OK);
} else {
ApiResponse errorResponse = new ApiResponse(500, "Failed to fetch weather data", 1, null);
return new ResponseEntity<>(errorResponse.toString(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}

Step 8 : Giving API access Key:

Go to application.properties and paste your API access key as shown below: Also set the server port to 2023 or whatever you wish to use.

weatherunion.api.key=dd**********************83

server.port = 2023

Step 9 : Running your application
Run your application and hit this api using Request Method GET.

localhost:2023/api/weather/

You need not to specify values of latitude and longitude as defaults are set. Although you will need to specify if you wish to get weather status of other places.

Response:

Custom Response with units of each parameter

See that you are able to hit the API and receive a response or not. If you are facing issues head out to Debugging section at the end of this article.

Congratulations you did it!

Step 10 : Future Scope
You are aware that APIs called easily from front end and consumed there with basic operations being handled well. Look for ideas that can help you in this project. One of which that I can share would be to make this as a small service of a bigger activity planning application. If the forecasted weather of the day is bad let the user know. Now that’s whole another story that how will you integrate ML. Stay tuned for my upcoming articles when I implement this.

Debugging :

Does your error look like this?

Error Response code: 406

OR

Error : Unauthorized Access //printed in the console

Print the final URL and use that in the postman along with your API access keys or simply uncomment the sout statements in the controller. Check if you are getting the response or not?

If Yes : Then check for spelling mistakes in the dto objects. Remember they are case sensitive.

If No: There can be several mistakes. Some of the trivial ones are these :
Your coordinates may be wrong.
Your API Key may be wrong.
Your might have used short form of latitude and longitude

If none of this works check your Response status code with the documentation and try to debug.

Likewise you can also reach out to me on LinkedIn.

--

--