JSON parsing with same attribute name

I am trying to parse the JSON Response from a Composite REST API call into a wrapper class. However, from the docs, “body” attribute in the response from a Composite Subrequest will be an

Object

in case of a successful request, and will be an

Array

for a failed request.

Successful request:

{
  "body" : {       
    "id" : "001R00000033I6AIAU",
    "success" : true,
    "errors" : [ ]
  },
  "httpHeaders" : { 
    "Location" : "/services/data/v38.0/sobjects/Account/001R00000033I6AIAU"  
  },
  "httpStatusCode" : 201,
  "referenceId" : "refAccount"
}

Failed Request:

{
  "body" : [ {
    "message" : "Email: invalid email address: Not a real email address",
    "errorCode" : "INVALID_EMAIL_ADDRESS",
    "fields" : [ "Email" ]
  } ],
  "httpHeaders" : { },
  "httpStatusCode" : 400,
  "referenceId" : "badContact"
}

How can I parse the response into a Wrapper class if the body attribute in the wrapper is an object or an array?

I am using JSON.deserialize:

jsonResponseList.add((JSONCompositeRespObj)JSON.deserialize(res.getBody(), JSONCompositeRespObj.class));

Answer

Since the success node isn’t a top level element, you can’t just use JSON.deserializeUntyped and get the element to determine the success, you need to rely on the type of the body.

Thankfully, JSON.deserializeUntyped provides the body element, and checking the type works very well here. An example is below.

String jsonFailure = '{ "body" : [ { "message" : "Email: invalid email address: Not a real email address", "errorCode" : "INVALID_EMAIL_ADDRESS", "fields" : [ "Email" ] } ], "httpHeaders" : { }, "httpStatusCode" : 400, "referenceId" : "badContact" }';
String jsonSuccess = '{ "body" : {"id" : "001R00000033I6AIAU", "success" : true, "errors" : [ ] }, "httpHeaders" : { "Location" : "/services/data/v38.0/sobjects/Account/001R00000033I6AIAU"}, "httpStatusCode" : 201, "referenceId" : "refAccount" }';

Map<String, Object> untypedSuccess = (Map<String, Object>)JSON.deserializeUntyped(jsonSuccess); 
Map<String, Object> untypedFailure = (Map<String, Object>)JSON.deserializeUntyped(jsonFailure); 

System.assertEquals(true, untypedFailure.get('body') instanceof List<Object>);
System.assertEquals(false, untypedSuccess.get('body') instanceof List<Object>);

There’s probably a more complex or elegant way to solve this problem, but frankly, I’d rather modify the API response than write code to work with this response, but that isn’t always possible.

Attribution
Source : Link , Question Author : SFDC Dev 27 , Answer Author : battery.cord

Leave a Comment