External integrations are one of the most common requirements in Salesforce applications. In this article, we will build a Weather Information Viewer using Salesforce technologies such as Visualforce, Apex, Named Credentials, Custom Metadata, and Wrapper Classes.
This project demonstrates how Salesforce can interact with external APIs and display real-time data inside a Salesforce UI. By the end of this guide, you will have a responsive Visualforce weather dashboard where a user can enter a city name and retrieve current weather information.
Table of Contents
What We Are Building
We will build a weather lookup application that allows users to:
- Enter a city name
- Click the Get Weather button
- Fetch real-time weather data from an external API
- Display weather details in a clean Visualforce interface
The weather data is fetched from:
https://api.weatherapi.com/v1/current.json
Example API request:
https://api.weatherapi.com/v1/current.json?key=API_KEY&q=Chennai&aqi=no
Architecture Overview
Our solution follows Salesforce integration best practices by avoiding hardcoded values and separating logic properly. The key components are:
| Component | Technology | Purpose |
|---|---|---|
| Frontend | Visualforce Page | User interface for city search and weather display |
| Controller | Apex Class | HTTP callout logic and data binding |
| API Config | Named Credentials | Secure external endpoint management |
| API Key | Custom Metadata | Configurable key storage outside code |
| Data Model | Wrapper Class | JSON response deserialization |
Named Credentials
Instead of hardcoding the API endpoint in Apex, we configure a Named Credential for security and maintainability.
Navigate to: Setup → Named Credentials, then configure:
- Name: weather_Api
- URL: http://api.weatherapi.com
This allows our Apex callout to reference the endpoint safely:
callout:weather_Api
Custom Metadata for API Key
We store the API key in Custom Metadata instead of hardcoding it in Apex. This allows us to update the configuration without changing any code.
Custom Metadata Type:
Weather_Config__mdt
Field:
ApiKey__c
Record:
DeveloperName: weather_Api_Key
What is a Wrapper Class in Salesforce?
A Wrapper Class is an Apex class used to represent complex data structures, especially when dealing with JSON responses from external APIs. When Salesforce receives a JSON response, it may contain nested objects such as location, current, and condition.
Instead of manually parsing JSON using maps, we create a wrapper class that mirrors the JSON structure, enabling automatic deserialization via JSON.deserialize().
Benefits of using Wrapper Classes:
- Cleaner, more readable code
- Automatic JSON deserialization
- Easy property access on nested objects
- Better maintainability over time
Weather API JSON Structure
The weather API returns a response structured as follows:
{
"location":{
"name":"Chennai",
"country":"India",
"localtime":"2026-03-13 16:32"
},
"current":{
"temp_c":31.2,
"humidity":71,
"condition":{
"text":"Sunny",
"icon":"//cdn.weatherapi.com/weather/64x64/day/113.png"
}
}
}
Wrapper Class Implementation
Using this wrapper class allows Salesforce to convert the JSON response automatically using JSON.deserialize()
public class WeatherResponseWrapper {
public Location location {get; set;}
public Current current {get; set;}
public class Location{
public String name {get; set;}
public String region {get; set;}
public String country {get; set;}
public String localtime {get; set;}
}
public class Current {
public Decimal temp_c {get; set;}
public Decimal temp_f {get; set;}
public Integer humidity {get; set;}
public Decimal wind_kph {get; set;}
public Condition condition {get; set;}
}
public class Condition{
public String text {get; set;}
public String icon {get; set;}
}
}
Apex Controller
The WeatherVFController handles the complete workflow:
- Retrieves the API key from Custom Metadata
- Builds the API request using Named Credentials
- Sends an HTTP callout to the weather service
- Parses the JSON response into the wrapper class
- Handles errors with user-friendly ApexPages messages
public with sharing class WeatherVFController {
public String cityName {get; set;}
public WeatherResponseWrapper weatherData {get; set;}
public void getWeather() {
try{
Weather_Config__mdt wcQuery = [
SELECT Id, Label, ApiKey__c
FROM Weather_Config__mdt
WHERE DeveloperName = 'weather_Api_Key'
LIMIT 1
];
String apiKey = wcQuery.ApiKey__c;
String endpoint = 'callout:weather_Api/v1/current.json?key='
+ apiKey + '&q=' + cityName + '&aqi=no';
HttpRequest req = new HttpRequest();
req.setEndpoint(endpoint);
req.setMethod('GET');
Http http = new Http();
HttpResponse res = http.send(req);
if(res.getStatusCode()==200){
weatherData = (WeatherResponseWrapper)
JSON.deserialize(res.getBody(), WeatherResponseWrapper.class);
} else {
ApexPages.addMessage(
new ApexPages.Message(
ApexPages.Severity.ERROR,
'Weather API Error'
)
);
}
} catch(Exception e){
ApexPages.addMessage(
new ApexPages.Message(
ApexPages.Severity.ERROR,
e.getMessage()
)
);
}
}
}
Visualforce Page
The Visualforce page provides a clean, responsive UI for users to search for weather information. It features:
- Gradient blue background with card-based layout
- City name input field with placeholder text
- Partial page refresh via reRender (no full page reload)
- Dynamic weather icon fetched from the API response
- Responsive grid displaying: City, Country, Local Time, Temperature, and Humidity
Visualforce Code
🌦 Weather Information
Your UI looks like this:

The page dynamically displays:
- City
- Country
- Local Time
- Temperature
- Humidity
- Weather Icon
Example Output
Example result for Chennai:
| Field | Value |
|---|---|
| City | Chennai |
| Country | India |
| Local Time | 2026-03-13 16:32 |
| Temperature | 31.2 °C |
| Humidity | 71% |
| Condition | Sunny |
Best Practices Demonstrated
| Named Credentials | Avoid hardcoded endpoints and manage external services securely |
| Custom Metadata | Store configuration values like API keys outside of code |
| Wrapper Classes | Handle JSON responses cleanly and efficiently |
| Error Handling | Provide user-friendly error messages via ApexPages |
| Clean UI Design | Use CSS styling to enhance Visualforce pages |
Final Thoughts
This project is a great example of how Salesforce can integrate with external systems while maintaining a secure and scalable architecture. Even though modern Salesforce development focuses heavily on Lightning Web Components, Visualforce remains valuable for learning Apex integrations and callout patterns.
Understanding these patterns helps developers build enterprise-grade integrations in Salesforce.

Kiran Sreeram Prathi
I’m Kiran Sreeram Prathi, a Salesforce Developer dedicated to building scalable, intelligent, and user-focused CRM solutions. Over the past five years, I’ve delivered Salesforce implementations across healthcare, finance, and service industries—focusing on both technical precision and user experience. My expertise spans Lightning Web Components (LWC), Apex, OmniStudio, and Experience Cloud, along with CI/CD automation using GitHub Actions and integrations with platforms such as DocuSign, Conga, and Zpaper. I take pride in transforming complex workflows into seamless digital journeys and implementing clean DevOps strategies that reduce downtime and accelerate delivery. Recognized by organizations like Novartis, WILCO, and Deloitte, I enjoy solving problems that make Salesforce work smarter and scale better. I’m always open to connecting with professionals who are passionate about process transformation, architecture design, and continuous innovation in the Salesforce ecosystem.
- Kiran Sreeram Prathi#molongui-disabled-link
- Kiran Sreeram Prathi#molongui-disabled-link
- Kiran Sreeram Prathi#molongui-disabled-link
- Kiran Sreeram Prathi#molongui-disabled-link





