function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Raghu Sharma 6Raghu Sharma 6 

process Rest API output

I'm calling external Rest API and recieving the output in the form of JSON. What is the best/easiest way to process this output in Apex?

I see that DOM (Document Object Model) approach only works with XML. Is there any standard function to convert JSON to XML?

Also see that there is a direct way of processing JSON as shown in below URL:
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_json_jsonparser.htm

Any sample code to process JSON output will be greatly helpful
Best Answer chosen by Raghu Sharma 6
R Z KhanR Z Khan
Hi Raghu,

I use the following app to process the JSON resposne for my rest API. Paste the response below and it will generate the class that you can use to deserialze the JSON later. It also creates tests, but i rpefer to write my own. Otherwise the tool is pretty good

https://json2apex.herokuapp.com/

All Answers

R Z KhanR Z Khan
Hi Raghu,

I use the following app to process the JSON resposne for my rest API. Paste the response below and it will generate the class that you can use to deserialze the JSON later. It also creates tests, but i rpefer to write my own. Otherwise the tool is pretty good

https://json2apex.herokuapp.com/
This was selected as the best answer
Bhaswanthnaga vivek vutukuriBhaswanthnaga vivek vutukuri
Create a wrapper class for storing response.

public class restResponse
{
     public string name;
     public List<string> interviews;
public restResponse() { }
}
Type resultType = Type.forName('restResponse');
CustomersResponse deserializeResults =       (CustomersResponse)JSON.deserialize(response, resultType);
System.debug('==========> deserialize() results = ' + deserializeResults);
Raghu Sharma 6Raghu Sharma 6
Hi RZ Khan

I was able to generate the apex class for the JSON response. I have below questions:

a. Will this class logic work even when there are multiple records returned in JSON. In my case, say 3 contact records are returned in JSON, will this process all of them?

b. How do I leverage this class from other classes? I mean I need to further play around these multiple records in another class and show them in VF page. So, any sample code or idea on leveraging this class will be helpful

Regards
Raghu
R Z KhanR Z Khan
Hi Raghu,

a. Yes, you would need to deserialzie it as a list of your wrapper class that was generated.
For example
String responseStrng = HTTPResponse.getBody();
List<JSONWrapper> n = (List<JSONWrapper>)JSON.deserialize(responseStrng, List<JSONWrapper>.class)
b. Paste it at the end of your controller as an inner class. 
Raghu Sharma 6Raghu Sharma 6
a. As suggested, I have added the code below in my controller class
          String responseStrng = res.getBody();
          List<JSON2Apex> n = (List<JSON2Apex>)JSON.deserialize(responseStrng, List<JSON2Apex>.class);

Also, added generated class at the end of controller class as it is.

b. When I tried to save the controller, first I got was below. I overcame by removing static keyword. Not sure, it this impacts the logic

Error: Compile Error: Only top-level class methods can be declared static at line 39 column 28

c. Now, I'm getting below error on compile. Basically this error is thrown on first class inside the generated class 'public class Audit {'
How to overcome this issue?

Error: Compile Error: unexpected token: 'class' at line 54 column 15
R Z KhanR Z Khan
Hi Raghu,

Is your inner class located before the last '}'? can you post your code here? the class should like liek following. Try to make it a private class unless you reference it form another class.
public class YourController{
     public void yourMethod(){
           //parse your JSON and do other logic
     }

          //Your generated class here
     private class JSONWrapper{
      
     }
}

 
Raghu Sharma 6Raghu Sharma 6
Thanks R Z Khan for your inputs.

I see that based on my JSON, default generated class has more classes inside it which may not be useful. So, I removed them. This fixed the issue.

Now when I try to execute the code, it is throwing the error as below:

System.JSONException: Malformed JSON: Expected '[' at the beginning of List/Set

Did you face similar issues? how to overcome this?
Raghu Sharma 6Raghu Sharma 6
I see that issue is coming from the below line and it did not execute further. Constructor for JSON2Apex is not even executed.

List<JSON2Apex> n = (List<JSON2Apex>)JSON.deserialize(responseStrng, List<JSON2Apex>.class);
R Z KhanR Z Khan

Raghu, i guess your wrapper handles the lsit. 
Try 
JSON2Apex n = (JSON2Apex)JSON.deserialize(responseStrng, JSON2Apex.class);
 

If it doesnt work can you psot the JSON2Apex class and JSON that you receive?
Also rename your class to something that would make more sense to you.

 

Raghu Sharma 6Raghu Sharma 6
Found the reason. I see that square brackets has to be added to my JSON output manually before processing it further. 
R Z KhanR Z Khan

Glad you found the problem. Please mark this question as resolved then and mark best answer that worked for you.
 

Thanks,
RZ

Raghu Sharma 6Raghu Sharma 6
It is working perfectly when the JSON has one record only. But if the JSON has multiple records in it, it is not working. How to fix this class to work for multiple records?
R Z KhanR Z Khan
Hi Raghu,

did you do the list conversion? Cna you post the wrapper and JSON?
R Z KhanR Z Khan
Hi Raghu,

the JSON that you posted for multip[le recordds is not only a lsit of Items records it has other variables such as offset, total, limit, links. I used JSON Parser to generate a new class. Please rename the inner classes adn modify as needed. Instead of deserializing you can jsut call the ItemsWrapper constructor and pass your json in the parameters. 
Good luck
public class ItemsWrapper{
	public cls_items[] items;
	public Integer total;	//134787
	public Integer offset;	//0
	public Integer limit;	//10
	public cls_links[] links;
	class cls_items {
		public String id;	//428448
		public String buildingName;	//Bayou Plaza
		public String streetNumber;	//-
		public String streetName;	//HWY 6 @ HWY. 6 & MAIN
		public String streetType;	//ST
		public String city;	//HITCHCOCK
		public String state;	//TX
		public String county;	//
		public String postalCode;	//77563
		public String country;	//US
		public cls_alternateAddresses[] alternateAddresses;
		public cls_location location;
		public String propertyType;	//Retail
		public cls_audit audit;
		public cls_geographicHierarchy[] geographicHierarchy;
		public Integer grossSquareFeet;	//-1
		public Integer netRentableAreaSquareFeet;	//-1
		public Integer availableSquareFeet;	//-1
		public Integer maxContiguousSquareFeet;	//-1
		public Integer yearBuilt;	//-1
		public Integer monthBuilt;	//-1
		public String class;	//Not Available
		public String address;	//- HWY 6 @ HWY. 6 & MAIN ST HITCHCOCK TX 77563
		public cls_links[] links;
	}
	class cls_alternateAddresses {
	}
	class cls_location {
		public Double latitude;	//29.3319
		public Double longitude;	//-94.94827
	}
	class cls_audit {
		public boolean isVerified;
		public String lastModifiedBy;	//
		public String lastModifiedOn;	//0001-01-01T00:00:00
		public String createdBy;	//
		public String createdOn;	//1900-01-01T01:00:00
	}
	class cls_geographicHierarchy {
		public String id;	//R1001
		public String name;	//TEXAS
		public String label;	//Region
		public Integer level;	//0
	}
	class cls_links {
		public String rel;	//self
		public String href;	//https://cbre.azure-api.net/api/enterprise/eim/properties/v2.0/properties
		public String title;	//properties
		public String method;	//GET
	}
	class cls_title {
	}
	public static ItemsWrapper parse(String json){
		return (ItemsWrapper) System.JSON.deserialize(json, ItemsWrapper.class);
	}
}

 
Raghu Sharma 6Raghu Sharma 6
Thanks R Z Khan for all your inputs

It started working after using string functions to extract the data within square brackets for both single and multiple records. Initial testing in progress but hopefully no issues will comeout.