JSON Deserialization in Salesforce


I have been several posts recently on the Developer Boards around JSON deserialization and some weird and convoluted ways to convert it into something that is useful for Salesforce.  Let’s talk about what I have found is the cleanest way to handle JSON deserialization.

JSON Payload

Let’s take a look at our JSON payload.  I am taking the payload from the docsample Heroku app since it’s an easy way to get consistent data from a webservice.

  "invoiceList": [
      "totalPrice": 5.5,
      "statementDate": "2011-10-04T16:58:54.858Z",
      "lineItems": [
          "UnitPrice": 1,
          "Quantity": 5,
          "ProductName": "Pencil"
          "UnitPrice": 0.5,
          "Quantity": 1,
          "ProductName": "Eraser"
      "invoiceNumber": 1
      "totalPrice": 11.5,
      "statementDate": "2011-10-04T16:58:54.858Z",
      "lineItems": [
          "UnitPrice": 6,
          "Quantity": 1,
          "ProductName": "Notebook"
          "UnitPrice": 2.5,
          "Quantity": 1,
          "ProductName": "Ruler"
          "UnitPrice": 1.5,
          "Quantity": 2,
          "ProductName": "Pen"
      "invoiceNumber": 2

So we can see here that the data provided is an invoice list and each invoice contains data and line items for that invoice.

JSON Deserialization

Data Structure

Now we need to create a data structure to hold our the JSON we deserialize

public class InvoiceWrapper {
    public class LineItem {
        public Double unitPrice {get; set;}
        public Double quantity {get; set;}
        public String productName {get; set;}

        public Double getLineItemTotal() {
            return this.unitPrice * this.quantity;

    public class Invoice {
        public Double totalPrice {get; set;}
        public DateTime statementDate {get; set;}
        public String contactnumber {get; set;}
        public List<LineItem> lineItems {get; set;}
        public Integer invoiceNumber {get; set;}

    public List<Invoice> invoiceList {get; set;}

This wrapper class now contains our two sub-classes (LineItem and Invoice) as well as our variable for our invoice list.  The nice thing about doing it as a class is we can add helper methods to also manipulate data.  There is a getLineItemTotal method that we can use in our display.

Data Parsing

Now we need to pull the data from the endpoint and using JSON deserialization push it into our data structure.

public class JSONDeserialize {
    public InvoiceWrapper wrapper {

    public void deserialize() {
        Http h = new Http();
        HttpRequest request = new HttpRequest();
        request.setHeader('Content-type', 'application/json');

        HttpResponse response = h.send(request);

        wrapper = (InvoiceWrapper) JSON.deserializeStrict(response.getBody(), InvoiceWrapper.class);

If your JSON data is going to change (or could change) you can use deserialize instead of deserializeStrict to make it not explode when the JSON deserialization happens.

Data Display

Now that we have a way to get the data in a meaningful structure, let’s display it on a Visualforce page

<apex:page controller="JSONDeserialize">
    <apex:form >
        <apex:pageBlock title="JSON Deserialize Response">
            <apex:pageBlockButtons >
                <apex:commandButton value="submit" action="{!deserialize}" reRender="invoiceBlock"/>
            <apex:pageBlockSection id="invoiceBlock" columns="1">
                <apex:repeat value="{!wrapper.invoiceList}" var="invoice">
                    <apex:pageBlockSection columns="2">
                        <apex:facet name="header">Invoice {!invoice.invoiceNumber}</apex:facet>
                        <apex:pageBlockSectionItem >
                            <apex:outputLabel value="Total Price" for="totalPrice" />
                            <apex:outputText value="{!invoice.totalPrice}" id="totalPrice" />
                        <apex:pageBlockSectionItem >
                            <apex:outputLabel value="Statement Date" for="statementDate" />
                            <apex:outputText value="{!invoice.statementDate}" id="statementDate" />
                    <apex:pageBlockSection columns="1">
                        <apex:facet name="header">Invoice {!invoice.invoiceNumber} Items</apex:facet>
                        <apex:pageBlockTable value="{!invoice.lineItems}" var="item" id="lineItems">
                            <apex:column value="{!item.productName}" headerValue="Product Name" />
                            <apex:column value="{!item.quantity}" headerValue="Quantity" />
                            <apex:column value="{!item.unitPrice}" headerValue="Unit Price" />
                            <apex:column value="{!item.lineItemTotal}" headerValue="Total" />

Now when we click the submit button we can see the data coming in and when it’s pressed we deserialize the data and reRender the section

JSON Deserialization in action

This entry was posted in Development, Salesforce and tagged , , . Bookmark the permalink.
  • JimBTek

    This article makes it really straightforward to see how to do this step by step. Would be interesting to have a second piece that includes storing the data in a Salesforce custom object, and perhaps even different ways of getting this data to sync 1-way or 2-ways. Thanks for the great article!

  • You mean extending this so that the data in InvoiceWrapper is stored into an Invoice__c object? Can you expand upon what you mean by “1-way or 2-ways” sync?

  • JimBTek

    Yeah storing the data in a custom object.

    1-way: Sync data from JSON to Salesforce ongoing (think syncing in invoices for read only purpose in Salesforce

    2-way: User edits the Invoice record in Salesforce and it pushes back through JSON to Heroku, etc.

    Currently on a project that does 2-way syncing of invoices between Salesforce and Quickbooks Online, but we use a 3rd party syncing tool that uses XML to map across the two. It would be interesting to see more of how to roll your own connection.

  • Jerry Clifft

    I would really like to see this write the data to a custom object/fields instead of displaying to visualforce.

  • I’ll try to write something up for you, but there are two ways to do this. You can do the object way above and add a method that converts the data to an sObject or if the incoming JSON is in the same format as your sObject you can just deserialize it directly using sObject.class

  • Hi, I just tried to use your method in my org but struggling to get the results.


  • I’ve replied back to your post

  • Hara Prasad Sahoo

    Just a small correction, I had to change the datatype of Quantity field to Double.
    public class lineitem{
    public Double unitprice{get;set;}
    public Double quantity{get;set;}
    public String productname{get;set;}

    rest all is good, works like a charm

  • It was already set as a double in the on the post. Did I miss a place?

  • Hara Prasad Sahoo

    my bad, i might have missed it:)

  • Hara Prasad Sahoo

    I was working on a similar task.
    I have tried to use a wrapper class to deserialise the json and put it into a wrapper class, which I have declared earlier.
    I am getting an error at this point below:
    jsonOutput results = (jsonOutput) JSON.deserialize(response.getBody(), jsonOutput.class);

    Error is :19:26:06:943 FATAL_ERROR System.JSONException: Malformed JSON: Expected ‘{‘ at the beginning of object

    please advise if I am missing anything here.

    public with sharing class WarehouseCalloutService {

    private static final String WAREHOUSE_URL = ‘https://th-superbadge-apex.herokuapp.com/equipment’;

    // wrapper class
    public class Jsonwrapper{
    public String x_id;
    public Boolean replacement;
    public Integer quantity;
    public String name;
    public Integer maintenanceperiod;
    public Integer lifespan;
    public Integer cost;
    public String sku;

    public class JsonOutput{
    public Jsonwrapper wrapper;
    public static void runWarehouseEquipmentSync(){
    Http h = new Http();
    HttpRequest request = new HttpRequest();
    request.setHeader(‘Content-type’, ‘application/json’);

    HttpResponse response = h.send(request);

    if (response.getStatusCode() == 200) {

    jsonOutput results = (jsonOutput) JSON.deserialize(response.getBody(), jsonOutput.class);
    system.debug(‘##’ + results);



  • The problem you are having is because you’re not parsing the JSON in the way that it is formatted. You need to parse a list of “Jsonwrapper” instead. Below I’ve renamed your “Jsonwrapper” class to be Equipment (to better line up with what it is)

    public class Equipment {
    /* Elements go here */

    /* Rest of http stuff goes here */

    List = (List) JSON.deserialize(response.getBody(), List.class);

  • Sagar Panwar

    Hey! Patrick Connelly, Thank you my friend. The example is great. It worked for me. I am new to salesforce and I have a question.
    Can we use the same process to fetch data from woo commerce to our salesforce. I don’t want to use external plugins.

  • Yes, you should be able to do this with any REST endpoint. I recommend going over the Apex Integration Services (specifically the Apex REST Callouts module) [1]. Be warned that depending on the number of licenses you have, you want to monitor your API limits. You may also want to look at implementing platform cache [2] to reduce the number of API calls you make, if your data doesn’t change super frequently.

    [1] https://trailhead.salesforce.com/modules/apex_integration_services
    [2] https://trailhead.salesforce.com/modules/platform_cache

  • Sagar Panwar

    “id”: 38,
    “parent_id”: 0,
    “number”: “38”,
    “order_key”: “wc_order_5b472b646db19”,
    “created_via”: “checkout”,
    “version”: “3.4.3”,
    “status”: “processing”,
    “currency”: “INR”,
    “date_created”: “2018-07-12T10:20:20”,
    “date_created_gmt”: “2018-07-12T10:20:20”,
    “date_modified”: “2018-07-12T10:20:20”,
    “date_modified_gmt”: “2018-07-12T10:20:20”,
    “discount_total”: “0.00”,

    My JSON is in this format. And I am getting the error
    Malformed JSON: Expected ‘{‘ at the beginning of object
    Error is in expression ‘{!deserialize}’ in component in page wooordersdatadisplay: Class.System.JSON.deserializeStrict: line 19, column 1
    Class.OrdersJSONDeserialize.deserialize: line 27, column 1

    My Wrapper class
    public class OrdersWrapper {
    public class Billing{
    public String first_name {get; set;}
    public String last_name {get; set;}
    public String company {get; set;}
    public String address_1 {get; set;}
    public String address_2 {get; set;}
    public String city {get; set;}
    public String state {get; set;}
    public String postcode{get; set;}
    public String country {get; set;}
    public String email {get; set;}
    public String phone {get; set;}

    public class Shipping {
    public String first_name {get; set;}
    public String last_name {get; set;}
    public String company {get; set;}
    public String address_1 {get; set;}
    public String address_2 {get; set;}
    public String city {get; set;}
    public String state {get; set;}
    public String postcode{get; set;}
    public String country {get; set;}

    public class LineItems{
    public Integer id {get; set;}
    public String name {get; set;}
    public Integer product_id{get; set;}
    public Integer variation_id {get; set;}
    public Integer quantity {get; set;}
    public Double tax_class {get; set;}
    public String subtotal {get; set;}
    public Double subtotal_tax{get; set;}
    public Double total{get; set;}
    public Double total_tax {get; set;}
    public List taxes {get; set;}
    public List metadata {get; set;}
    public String sku {get; set;}
    public Integer price {get; set;}

    public class TaxLines{


    public class ShippingLines{
    public Integer id {get; set;}
    public String method_title {get; set;}
    public String method_id {get; set;}
    public String instance_id {get; set;}
    public Double total {get; set;}
    public Double total_tax {get; set;}
    public List taxes {get; set;}
    public List metadata {get; set;}

    public class Taxes{

    public class MetaData{
    public Integer id {get; set;}
    public String key {get; set;}
    public String value {get; set;}

    public class FeeLines{}
    public class CouponLines{}
    public class Refunds{}

    public class Links{
    public List self {get; set;}
    public List collection {get; set;}
    public List customer {get; set;}
    public class Self{
    public String href {get; set;}
    public class Collection{
    public String href {get; set;}
    public class Customer {
    public String href {get; set;}

    public class Orders{
    public Integer id {get; set;}
    public Integer parent_id {get; set;}
    public String numbero {get; set;}
    public String order_key {get; set;}
    public String created_via {get; set;}
    public String version {get; set;}
    public String status {get; set;}
    public String currency_o {get; set;}
    public DateTime date_created {get; set;}
    public DateTime date_created_gmt {get; set;}
    public DateTime date_modified {get; set;}
    public DateTime date_modified_gmt {get; set;}
    public Double discount_total {get; set;}
    public Double discount_tax {get; set;}
    public Double shipping_total {get; set;}
    public Double shipping_taxt {get; set;}
    public Double cart_tax {get; set;}
    public Double total {get; set;}
    public Double total_tax {get; set;}
    public String prices_include_tax {get; set;}
    public Integer customer_id{get; set;}
    public String customer_ip_address {get; set;}
    public String customer_user_agent {get; set;}
    public String customer_note {get; set;}
    public String payment_method {get; set;}
    public String payment_method_title {get; set;}
    public String transaction_id {get; set;}
    public String date_paid {get; set;}
    public String date_paid_gmt {get; set;}
    public String date_completed {get; set;}
    public String date_completed_gmt {get; set;}
    public String cart_hash {get; set;}

    public List billing {get; set;}
    public List lineitems {get; set;}
    public List metadata{get; set;}
    public List taxlines {get; set;}
    public List feelines {get; set;}
    public List coupons_lines {get; set;}
    public List links {get; set;}


    public List orders {get; set;}

    public class OrdersJSONDeserialize {
    public OrdersWrapper wrapper{

    public void deserialize(){
    Http h = new Http();
    HttpRequest request = new HttpRequest();

    String endurl = ‘…’;
    request.setHeader(‘Content-type’, ‘application/json’);

    //System.debug(‘Before response — start — ‘);

    HttpResponse response = h.send(request);

    //String jsonString = ‘{“orders” : ‘+ response.getBody() +’}’;
    String jsonString = response.getBody();

    System.debug(‘url is: ‘+endurl);

    System.debug(‘After response –‘ + jsonString);

    wrapper = (OrdersWrapper) JSON.deserializeStrict(jsonString, OrdersWrapper.class);
    //List wrapper = (List)JSON.deserialize(response.getBody(), List.class);


  • The line you commented out is required. The JSON is not valid because it’s just an array. JSON has to start with { not [ which is why the line is ‘{“orders”: ‘ + response.getBody() + ‘}’ to make it valid JSON.

  • Sagar Panwar

    But I am getting this from woocommerce rest api

  • Again, this is because the data coming back from woocommerce isn’t technically valid JSON. All valid JSON has to be surrounded by {}. That’s why in the code we surround the body with an element to make it valid JSON. If you do what I suggest above, you won’t get the parsing error

  • nti

    Hi Pat ,
    I went through your code and on the basis of that I have written some code but its of no use.So if u get time to look into it please where is the problem in the code.

    I am not getting any error but when I run it anonymously and try to see debug statements its only showing null value to me.

    I have called news api but i can only see null results.

    I have all the payload needed classes inside newsapi class.All of them are inner classes of NewsApi class.

    Public class Newsapi

    public NewsApi news
    public void ApexNes()

    Http http = new Http();
    HttpRequest request = new HttpRequest();
    request.setHeader(‘Content-Type’, ‘application/json;charset=UTF-8’);
    HttpResponse response = http.send(request);
    //system.debug(‘Response body has the following item’+response.getbody());


    System.debug(‘The variable under has the following values’+news);

    //System.debug(‘The variable under has the following values’+news.status);


    public class JSON2Apex {

    public String status {get;set;}
    public Integer totalResults {get;set;}
    public List articles {get;set;}


    public class Articles {
    public Source source {get;set;}
    public Object author {get;set;}
    public String title {get;set;}
    public String description {get;set;}
    public String url {get;set;}
    public String urlToImage {get;set;}
    public String publishedAt {get;set;}
    public String content {get;set;}

    public class Source
    public String id {get;set;}
    public String name {get;set;}



  • The problem is you’re deserializing into the wrong class. You should instead have

    public JSON2Apex news { get; set; }

    news=(JSON2Apex)json.deserialize(response.getBody(), JSON2Apex.class);

    I’d recommend renaming that highest level class to something like Headlines

  • Imran

    Hi Patrick,

    With the help of your post regarding the json deserialization I want to display the json response on a vf page. But I am getting null value did not understand why .

    Endpoint url: http://services.groupkt.com/country/get/all

    public class HttpCountryIsoCodes{

    Public string strSearchParam {get;set;}
    public string strResult {get;set;}
    public RestResponseWrapper wrapper;

    public string strBaseUrl;

    public HttpCountryIsoCodes(){
    strBaseUrl = ‘http://services.groupkt.com/country/’;
    wrapper = new RestResponseWrapper();

    public void getAllIsoCodes(){
    Http objHttp = new Http();
    HttpRequest objRequest = new HttpRequest();
    objRequest.setEndpoint(strBaseUrl + ‘get/all’);
    HttpResponse objResponse = objHttp.send(objRequest);
    this.strResult = objResponse.getBody();

    wrapper = RestResponseWrapper.doParse(this.strResult);

    system.debug(‘ :: strResult is :: ‘+ this.strResult);
    system.debug(‘ :: wrapper response is :: ‘+wrapper);


    Datamodel wrapper class to deserialize json response

    public class RestResponseWrapper{

    public class Result{
    public string name {get;set;}
    public string alpha2_code {get;set;}
    public string alpha3_code {get;set;}

    public class RestRes{
    public list messages {get;set;}
    public list lstResult {get;set;}

    public RestRes objRestRes {get;set;}

    public static RestResponseWrapper doParse(string strResult){
    return (RestResponseWrapper) system.JSON.deserialize(strResult, RestResponseWrapper.class);



    Any kind of help would be really appreciated.

  • Your wrapper is a little bit wrong because you don’t have it deep enough. You need to have the following (note that I renamed the main class as RestResponseHandler because it’s a bad idea to use deserialize on a class that has methods and other variables). Also, the class level variables have to match the name of the variable in your JSON.

    public class RestResponseHandler {
    public class Result {
    public String name {get; set;}
    public String alpha2_code {get; set;}
    public String alpha3_code {get; set;}

    public class RestRes {
    public List messages {get; set;}
    public List result {get; set;}

    public class RestResponseWrapper {
    public RestRes RestResponse {get; set;}

    public static RestResponseWrapper doParse(string strResult) {
    return (RestResponseWrapper) system.JSON.deserialize(strResult, RestResponseWrapper.class);

  • I’d have to see what the JSON data looks like when it comes back from your external service. It’s most likely that you just don’t have the right structure to your classes.

  • Imran

    Thanks Pat !!!
    I figured out same thing as well and modified . Now it’s working perfectly…
    Thanks a lot

    One more thing here,
    I need to display the country name , and code in a visual force page and display only 20 records per page.
    When I use standard set controller am getting error .
    Standard set controller will not work in this case ???
    Do I need to custom pagination here ???

  • Yes, you’ll have to build your own custom pagination since the standard set controller only operates on sObjects

  • Imran

    Thanks Patrick .

  • Nadeer Ravi

    Hi Patrick,

    Can you please help me below.

    Account a = new Account(Name=’json ex’,Test__c=’text’, Number__c=’2′);
    insert a;
    String accountListJSON = JSON.serialize( Database.query( ‘select id,Test__c, Number__c from account ‘ ) );

    list records = (list) JSON.deserialize(accountListJSON, list.class);

    public class PersonAccountWrapper
    public decimal Number{get; set;}
    public string test{get; set;}

    but values are not parsing to records. can you please let me know any standard methods for this. we need wrapper.

  • The reason is that your JSON isn’t in the format that your wrapper is in. I would ask why you need a wrapper for this. You could just deserialize it back into a list

    Account a = new Account(Name='json ex', Test__c='text', Number__c='2');
    insert a;
    String accountListJSON = JSON.serialize(Database.query('select id, Test__c, Number__c from Account'));
    List records = (List) JSON.deserialize(accountListJSON, List.class);

    If you feel you have to use a wrapper class you can do

    public class PersonAccountWrapper {
    public Decimal Number {get; set;}
    public String Test {get; set;}

    Account a = new Account(Name='json ex', Test__c='text', Number__c='2');
    insert a;
    String accountListJSON = JSON.serialize(Database.query('select id, Test__c, Number__c from Account')).replaceAll('__c', '');
    List records = (List) JSON.deserialize(accountListJSON, List.class);

  • Lanke RamyaSree

    Hoe to write test class for this could you please helpme

    public class JSON2Apex {

    public class Industries {
    public String INDUSTRY_CODE;
    public String INDUSTRY_GLOBAL_CODE;
    public String INDUSTRY_TYPE_CODE;

    public HeaderDetails HeaderDetails;
    public List EmployeeDetails;
    public String ResponseMessage;

    public class TelephoneNumbers {

    public class Organizations {
    public String ORGANIZATION_CODE;

    public class Levels {
    public String LEVEL_HIERARCHY_LEVEL;
    public String LEVEL_CODE;
    public String LEVEL_DESCRIPTION;
    public String LEVEL_GLOBAL_CODE;
    public String LEVEL_TYPE_CODE;
    public class Statuses
    public string STATUS_DESCRIPTION;
    public string STATUS_TYPE_DESCRIPTION;
    public string STATUS_HIERARCHY_LEVEL;

    public class HeaderDetails {
    public String SystemID;
    public String UserID;
    public String TransactionID;

    public class Functions {
    public String FUNCTION_CODE;
    public String FUNCTION_GLOBAL_CODE;
    public String Function_TYPE;
    public String FUNCTION_TYPE_CODE;

    public class Languages {
    public String LANGUAGE_TYPE_CODE;
    public String LANGUAGE_CODE;

    public class Roles {
    public String ROLE_CODE;
    public String ROLE_DESCRIPTION;
    public String ROLE_ADDITIONAL_1;
    public String ROLE_TYPE_CODE;

    public class Emails {
    public String EMAIL_ADDRESS;
    public String EMAIL_SAM_ACCOUNT;
    public String EMAIL_TYPE_CODE;


    public class Types {
    public String TYPE_DESCRIPTION;
    public String TYPE_GLOBAL_CODE;
    public String TYPE_TYPE_CODE;
    public String TYPE_TYPE_DESCRIPTION;

    public class EmployeeDetails {
    public String ActionCode;
    public Integer RecordKey;
    public String LAST_MODIFIED_DATE;
    public String EMPLOYEE_CODE;
    public Integer EMPLOYEE_GUID;
    public String EMPLOYEE_ID;
    public String MEMBER_FIRM_ID;
    public String PREFERRED_FIRST_NAME;
    public String PREFERRED_LAST_NAME;
    public String FIRST_NAME;
    public String LAST_NAME;
    public String LOGIN;
    public String MIDDLE_NAME;
    public String NICKNAME;
    public String GLOBAL_EMPLOYEE_CODE;
    public String NAME_PREFIX;
    public String NAME_SUFFIX;
    public String NATIVE_NAME;
    public String SECOND_LAST_NAME;
    public List Emails;
    public List TelephoneNumbers;
    public String JOB_TITLE_DESCRIPTION;
    public String JOB_TITLE_CODE;
    public String COST_CENTER_CODE;

    //public sObject Designations;
    public List Functions;

    public list Industries;
    public List Languages;
    public List Organizations;

    //public sObject RelatedEmployees;
    public List Roles;

    public list Types;
    public list Statuses;

    //public sObject PAY_AREA;

    //public sObject BIRTH_YEAR;

    //public sObject CURRENCY;

    //public sObject DTT_ACTION_DATE;

    //public sObject DTT_ACTION_TYPE;


    //public sObject DTT_DATE_OF_TASK;

    //public sObject DTT_JOB_TITLE;

    //public sObject DTT_JOB_TITLE_DESCRIPTION;

    //public sObject DTT_PERSONNEL_AREA;

    //public sObject DTT_POSITION_DESCRIPTION;

    //public sObject DTT_REASON_FOR_ACTION;

    //public sObject EMPLOYEE_PERCENTAGE;

    //public sObject GENDER;

    //public sObject SALARY;

    //public sObject PAY_SCALE_GROUP;

    //public sObject PAY_SCALE_LEVEL;
    public List Levels;
    public String COUNTRY_CODE;
    public String COUNTRY_DESC;
    public String AD_CITY;
    public String OFFICE_LOCATION;
    public String OFFICE_CODE;
    public String OFFICE_DESCRIPTION;
    public String REGION_CODE;
    public String TELEPHONE_EXTENSION;
    public String MAILING_ADDRESS_LINE_1;
    public String MAILING_ADDRESS_LINE_2;
    public String MAILING_ADDRESS_LINE_3;
    public String REGION_DESCRIPTION;
    public String ADDRESS_COUNTRY_CODE;
    public String ADDRESS_LINE_1;
    public String ADDRESS_LINE_2;
    public String ADDRESS_POSTAL_CODE;
    public String ADDRESS_STATE_CODE;
    public String ADDRESS_LINE_3;
    public String FAX_NUMBER;
    public String OFFICE_TYPE_CODE;
    public String GREENWICH_MEAN_TIME;
    public String FAX_AREA_CODE;
    public String FAX_COUNTRY_CODE;
    public String FAX_EXTENSION;
    public String TELEPHONE_NUMBER;
    public String OFFICE_ID;

    //public sObject Qualifications;
    public String HIRE_DATE;
    public String TERMINATION_DATE;
    public String REHIRE_DATE;

    //public sObject MODULE_CODE;

    //public sObject MODULE_DESCRIPTION;

    //public sObject VENDOR_CODE;

    //public sObject VENDOR_DESCRIPTION;

    /*public static JSON2Apex parse(String json) {
    return (JSON2Apex) System.JSON.deserialize(json, JSON2Apex.class);

  • Chandra Kanth

    Hi Patrick,
    How to pass the deserialized data to Comparable interface class


  • You simply make the class you deserialize the data into implement comparable

  • Chandra Kanth

    Account a = new Account(Name=’json ex’, Test__c=’text’, Number__c=’2′);
    insert a;
    String accountListJSON = JSON.serialize(Database.query(‘select id, Test__c, Number__c from Account’));
    List records = (List) JSON.deserialize(accountListJSON, List.class);

    In the above example we will be getting the List of Account Records. I want to sort the Account list based on the fields.
    If i use Comparable interface, we cannot pass list of records to comparable constructor right, how to overcome this ?

  • There is no reason to do that in a comparable class but instead do it in the SOQL. You are going to have better performance results by doing it there. Also if you’re not generating the query dynamically there’s no reason to query and deserialize as this will just increase your heap size. Instead you should just bind the query directly to the object list.

    If you feel you have to use dynamic SOQL then you will have to create a class that implements comparable and has a constructor based off a single account object. Then just iterate over each of your account instances adding it to your list of comparable objects then calling sort.

  • Chandra Kanth

    My requirement is to get the data using callout and parse(deserialize) the Json data and sort it based on the fields

  • Then your example isn’t useful because that’s not what you’re doing.

  • Chandra Kanth

    Thanks for the response

  • LearnerNewbie

    Hi Patrick,

    Thank you so much for your post. It is really helpful and easy to understand.
    I would like to know whether do you have a post that is about how we can get input from a user in salesforce and then take this input and send it to external server and use the API(this API will automatically parse the input and output it in JSON format) there to parse the input that return the output in JSON format?

  • I kinda do that in an article about getting data from Runkeeper. If you combine that with the section in the Apex REST Callouts Trailhead, it should get you most of the way there.

  • Ratnam Raja

    Hi Patrick,
    what if i have dynamic json response(i mean you know dynamic SOQL Result for different Objects)?How can I write a Wrapper for that?

  • That would be pretty tough. I would have a class that has all the fields you would expect and then use the normal JSON.deserialize method. If you’re doing it all in Apex, the better way in my opinion would be to have a class with a constructor that determines object type that then sets your member variables.

    public class Wrapper {
    public String name;
    public String Id;
    public String customAttribute;

    private setFields(Account a) {
    this.Name = a.Name;
    this.customAttribute = a.Attribute__c;

    private setFields(Contact c) {
    this.Name = c.Name;
    this.customAttribute = c.OtherAttribute__c;

    public Wrapper() {}

    public Wrapper(sObject obj) {
    this.Id = obj.Id;

    switch on obj.getSObjectType().getDescribe().getName() {
    when Schema.Account.getSObjectType().getDescribe().getName() {
    this.setFields((Account) obj);
    when Schema.Contact.getSObjectType().getDescribe().getName() {
    this.setFields((Contact) obj);