Mastering JSON in Salesforce Apex: The Complete Guide to System.JSON

💡 Mastering JSON in Salesforce Apex: The Complete Guide to System.JSON 

In today’s API-first world, working with JSON is no longer optional — it’s essential. Whether you’re integrating Salesforce with external platforms, transforming data in LWC, or powering dynamic UIs, Salesforce’s System.JSON class is your go-to toolbox. 

In this guide, we’ll walk through all the key methods of the System.JSON class in Apex — complete with examples and best practices. 

🚀 What Is System.JSON? 

The System.JSON class provides static methods for: 

  • Serializing Apex objects into JSON 
  • Deserializing JSON strings into Apex objects 
  • Generating or parsing JSON programmatically 

 🔍 Why Should You Care? 

System.JSON is vital for: 

  • REST API integrations 
  • Transforming Apex/LWC data 
  • AI agents and dynamic interfaces 
  • Storing or handling loosely-typed or external data 

 📘 Core Methods with Examples 

  1. createGenerator(prettyPrint)

Build JSON manually using code. 

apex 

public static String buildDynamicJson() { 

    JSONGenerator gen = JSON.createGenerator(true); // Pretty print 

    gen.writeStartObject(); 

    gen.writeStringField(‘accountName’, ‘ACME Corp’); 

    gen.writeNumberField(’employees’, 120); 

    gen.writeBooleanField(‘active’, true); 

    gen.writeEndObject(); 

    return gen.getAsString(); 

} 

Best Use: Custom API payloads with conditional fields
Use true to make debugging easier. 

 

  1. createParser(jsonString)

Parse JSON token-by-token. 

apex 

public static void parseWithControl(String jsonInput) { 

    JSONParser parser = JSON.createParser(jsonInput); 

    while (parser.nextToken() != null) { 

        if (parser.getCurrentToken() == JSONToken.FIELD_NAME && parser.getText() == ‘status’) { 

            parser.nextToken(); // Move to value 

            System.debug(‘Status: ‘ + parser.getText()); 

        } 

    } 

} 

Best Use: Large/nested JSON, fine-grained control
Avoid unless needed. Use deserialize() when possible. 

 

  1. deserialize(jsonString, apexType)

Convert JSON into a known Apex class. 

apex 

public class Order { 

    public String id; 

    public Decimal total; 

} 

 

public static Order parseOrder(String jsonInput) { 

    return (Order) JSON.deserialize(jsonInput, Order.class); 

} 

Best Use: Standard integrations with structured payloads
💡 Extra JSON fields are ignored safely. 

 

  1. deserializeStrict(jsonString, apexType)

Same as deserialize() but fails on extra fields. 

apex 

public class Invoice { 

    public String invoiceNumber; 

    public Decimal amount; 

} 

 

public static Invoice parseInvoiceStrict(String jsonInput) { 

    return (Invoice) JSON.deserializeStrict(jsonInput, Invoice.class); 

} 

Best Use: Enforcing strict data contracts
Use for critical systems or validation layers 

 

  1. deserializeUntyped(jsonString)

Convert JSON into a Map<String, Object> or List<Object> 

apex 

String jsonInput = ‘{“name”:”Widget”,”stock”:25,”active”:true}’; 

Map<String, Object> product = (Map<String, Object>) JSON.deserializeUntyped(jsonInput); 

System.debug(‘Stock: ‘ + product.get(‘stock’)); 

Best Use: Unknown or dynamic JSON payloads
Handle data types carefully — always cast explicitly. 

 

  1. serialize(objectToSerialize)

Convert Apex objects into compact JSON strings. 

apex 

public class Customer { 

    public String name; 

    public String email; 

} 

 

public static String toJson() { 

    Customer c = new Customer(); 

    c.name = ‘Ada Lovelace’; 

    c.email = ‘ada@tech.io’; 

    return JSON.serialize(c); 

} 

Best Use: Outbound API calls or object logging
💡 Use DTOs instead of raw SObjects. 

 

  1. serialize(objectToSerialize, suppressApexObjectNulls)

Same as serialize(), but removes null values. 

apex 

public class ContactWrapper { 

    public String firstName; 

    public String lastName; 

    public String nickname; // might be null 

} 

 

public static String toCleanJson() { 

    ContactWrapper cw = new ContactWrapper(); 

    cw.firstName = ‘Grace’; 

    cw.lastName = ‘Hopper’; 

    return JSON.serialize(cw, true); // nickname will be removed 

} 

Best Use: Clean, efficient API payloads
💡 Helps reduce payload size 

 

  1. serializePretty(objectToSerialize)

Generate indented JSON for humans. 

apex 

public class DebugHelper { 

    public static void logObject(Object obj) { 

        System.debug(JSON.serializePretty(obj)); 

    } 

} 

Best Use: Debugging and developer logs
Don’t use in production APIs — adds unnecessary size 

 

  1. serializePretty(objectToSerialize, suppressApexObjectNulls)

Readable and clean JSON — great for documentation. 

apex 

public static String prettyAndClean() { 

    Map info = new Map{ 

        ‘name’ => ‘Alan Turing’, 

        ‘role’ => null 

    }; 

    return JSON.serializePretty(info, true); // role omitted 

} 

Best Use: API mocking, test logs
💡 Ideal for dev environments, not production 

🧠 Summary Table: What to Use When? 

Method  Use Case 
serialize()  Quick conversion to JSON 
serializePretty()  Developer-friendly readable logs 
serialize(…, true)  Compact payloads without nulls 
deserialize()  Flexible parsing with extra field support 
deserializeStrict()  Enforced contract with strict structure 
deserializeUntyped()  Dynamic/unknown JSON payloads 
createGenerator()  Manual construction of complex JSON 
createParser()  Large streams, low-level control 

 

📚 Recommended Reading 

🧵 Final Thoughts 

  • Use deserializeStrict() when data accuracy is non-negotiable. 
  • Prefer DTOs over raw SObjects for serialization. 
  • deserializeUntyped() gives flexibility — but handle with care. 
  • 🎯 Pretty JSON = for devs. Compact JSON = for machines. 

 

Leave a Comment

Your email address will not be published. Required fields are marked *