JSON Serialization and Callouts
By the end of this lesson, you'll be able to:
- Make an HTTP callout from Apex using Http, HttpRequest, and HttpResponse
- Parse a JSON response using JSON.deserializeUntyped for dynamic shapes
- Parse a JSON response into a typed Apex class using JSON.deserialize
Prerequisites: "Named Credentials and External Credentials"
Making a Callout
HttpRequest request = new HttpRequest();
request.setEndpoint('callout:Weather_API/current?city=Cape+Town');
request.setMethod('GET');
request.setHeader('Content-Type', 'application/json');
Http http = new Http();
HttpResponse response = http.send(request);
HttpRequest describes the call (endpoint, method, headers); Http.send() actually performs it and returns an HttpResponse — this is the Apex equivalent of the browser's fetch, used here because only Apex can perform the callout at all (Lesson 1).
Parsing JSON Responses
// Dynamic/unknown shape — a generic Map
Map<String, Object> data = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
Decimal temperature = (Decimal) data.get('temperature');
// Known, stable shape — a typed Apex class
public class WeatherResponse {
public Decimal temperature;
public String conditions;
}
WeatherResponse weather = (WeatherResponse) JSON.deserialize(response.getBody(), WeatherResponse.class);
JSON.deserializeUntyped produces a generic Map<String, Object> — flexible, but every value needs an explicit cast and there's no compile-time checking of property names. JSON.deserialize into a matching Apex class is preferred whenever the response shape is stable and known in advance — it gives compile-time-checked, typed property access instead.
A Worked Example
public with sharing class WeatherService {
public static WeatherSummary getCurrentWeather(String city) {
HttpRequest request = new HttpRequest();
request.setEndpoint('callout:Weather_API/current?city=' + EncodingUtil.urlEncode(city, 'UTF-8'));
request.setMethod('GET');
HttpResponse response = new Http().send(request);
WeatherResponse raw = (WeatherResponse) JSON.deserialize(response.getBody(), WeatherResponse.class);
return new WeatherSummary(raw.temperature, raw.conditions);
}
}
The raw API response is deserialized into an internal WeatherResponse class, then mapped into a WeatherSummary wrapper (Module 7's DTO pattern) — exactly the kind of clean boundary that decouples the component from the external API's own response shape.
Exercise
Write the Apex code to deserialize a JSON string jsonBody into a typed StockQuote class with fields symbol (String) and price (Decimal).
Show hint
Use JSON.deserialize with a cast.
Exercise
Challenge: explain, as a comment, why JSON.deserialize into a typed class is generally preferred over JSON.deserializeUntyped when the response shape is known and stable.
Show hint
Think about what each approach checks (or doesn't check) at compile time.
JSON Serialization and Callouts Quiz
My Notes
Log in to keep private notes on this lesson.
Questions about this lesson
No questions yet — be the first to ask.
Log in to ask a question about this lesson.
Summary
Http/HttpRequest/HttpResponse perform the actual callout, and Apex's JSON utilities turn the raw response text into either a flexible generic structure or a strongly-typed class, depending on how much the response shape is known in advance.