The method JSON.deserializeUntyped works well for this type of problem. What you get returned is a map:
Map<String, Object> m = (Map<String, Object>) JSON.deserializeUntyped(jsonString);
You can use the normal map methods to get hold of the keys or to see if a key is present. So for example to access the "ideal" list items:
List<Object> ideals = (List<Object>) m.get('ideal');
if (ideals != null) {
for (Object ideal : ideals) {
String product = (String) ideal('product');
String percent = (String) ideal('percent');
String dollarAmount = (String) ideal('dollarAmount');
...
}
}
Because it is known that the data is a list (array) I've just cast the object to a list. If the content is of very unpredictable type you can also use instanceof
tests in your logic.
Here is your JSON having been formatter by http://jsonformatter.curiousconcept.com/; this sort of formatting makes the JSON easier to understand:
{
"ideal":[
{
"product":"4",
"percent":"25",
"dollarAmount":"11250"
},
{
"product":"5",
"percent":"23",
"dollarAmount":"10350"
},
{
"product":"3",
"percent":"20",
"dollarAmount":"9000"
},
{
"product":"8",
"percent":"18",
"dollarAmount":"8100"
},
{
"product":"7",
"percent":"15",
"dollarAmount":"6750"
}
],
"idealFiltered":[
{
"product":"4",
"percent":"25",
"dollarAmount":"11250"
},
{
"product":"5",
"percent":"23",
"dollarAmount":"10350"
},
{
"product":"3",
"percent":"20",
"dollarAmount":"9000"
},
{
"product":"8",
"percent":"18",
"dollarAmount":"8100"
},
{
"product":"7",
"percent":"15",
"dollarAmount":"6750"
}
],
"InBudget":[
{
"product":"4",
"percent":"70",
"dollarAmount":"7000"
},
{
"product":"8",
"percent":"30",
"dollarAmount":"3000"
}
]
}
If you have any specific requirement regarding JSON structure, you need to go for JSON Generator. But if you are okay with the JSON syntax JSON.serialize() is giving, that is more than enough.
Regarding serializing all child relations of account, you can use JSON.serialize() itself. You need to query child relationships also while querying account. Check below example,
List<Account> accounts = [SELECT Id, Name, Phone, Fax, Website,
(SELECT Id,Name FROM Contacts)
FROM Account
WHERE Name =: AccountName];
if(!accounts.isEmpty()){
String jsonData = JSON.serialize(accounts[0]);
}
Try debugging the jsonData string. If that JSON format is not good for you, go ahead and create it in your own format using JSON Generator.
Best Answer
Your data model is analogous in levels to Opportunity - OpportunityLineItem - PricebookEntry - Product2
If you use SFDC Workbench REST Explorer with this query
You'll see how SFDC will JSON serialize the results:
If your target system for this JSON happens to also be SFDC, the structure is super convenient as it can be deserialized by the target system directly into sobjects.
However, if your target system has its own JSON structure, you are best of modelling that with inner classes as @susanoochidori suggests. You'll need to do the aforementioned SOQL in your APEX (changing to your custom objects from the OOB example I used) and then, map with assignment statements and inner class instanatiation the values returned from SOQL. Finally, serialize
OuterWrapper
.Put another way, you may need to work backwards from the JSON signature expected by the target system into a corresponding APEX outer with inner classes object model