1

We are moving slowly to the Confluence Kafka/Hydra/SF Platform Events structure for our integrations. On some of the SF Platform Events we have fields that are going to be the containers of several JSON payloads. The idea is that for some cases we are going to receive a json payload on a long text area field and them we are going to deserialize them and pass their content to an APEX class.

The Json I'm trying to deserialize into an apex class is this one, well... kind off:

{
"fields": [{
        "name": "orderId",
        "type": "string"
    },
    {
        "name": "stepStatuses",
        "type": [
            "null",
            {
                "items": {
                    "fields": [{
                            "name": "stepName",
                            "type": "string"
                        },
                        {
                            "name": "status",
                            "type": "string"
                        },
                        {
                            "name": "start",
                            "type": [
                                "null",
                                "long"
                            ]
                        },
                        {
                            "name": "end",
                            "type": [
                                "null",
                                "long"
                            ]
                        }
                    ],
                    "name": "stepStatus",
                    "type": "record"
                },
                "type": "array"
            }
        ]
    }
],
"name": "OrderStepsModified",
"namespace": "xxxxxxxx.commercex2c.hydra",
"type": "record"
}

There are a few simple problems that are easy to overcome but there is something I can't figurate out how to make it work. Is this part:

"type": [
        "null",
        {

I'm using the replace method to make a distinction between "type":[] and "type":"String", that is all fine... the problem, or the question is ... How can I deserialize that "null" and pass it to my class? It is just a value without a key so I'm wondering how to go around this.. Anyone? Thanks!

1
  • 1
    That JSON is "broken." It should be null, not "null". If that can't be fixed, you're in for a lot of unnecessary code.
    – sfdcfox
    Aug 10, 2021 at 15:18

1 Answer 1

3

The "null" should be null, without quotes. The former is a string, the latter is the lack of a value, which is what you want, since the structure implies that you have the following representation in Apex:

public class Field {
  public String name, type;
}
public class Item {
  public Field[] fields;
}
public class Type_X {
  public Item[] items;
}
// More layers not relevant here

In order to use automatic parsing (via JSON.deserialize), your JSON has to be correct. As it stands, your JSON would have to be parsed manually by JSON.deserializeUntyped or JSONParser, which is a lot more, complicated code.

If you can't fix that string, then you'll need to use a manual parsing technique.

Note that arrays, denoted by [], do not have "keys"; they are an ordered list of values (as demonstrated in the above wrappers).

As it is, since type at the field level appears to be dynamic, you'll probably need manual parsing anyways, which is a major pain.

What you'll end up having to do is something more like:

Map<String, Object> root = (Map<String, Object>)JSON.deserializeUntyped(jsonSource);
List<Object> fields = (List<Object>)root.get('fields');
for(Object field: fields) {
  String name = (String)field.get('name');
  Object typeVal = field.get('type');
  if(typeVal instanceOf String) {
    // Do something here
  } else if(typeVal instanceOf List<Object>) {
    for(Object innerTypeVal: (List<Object>)typeVal) {
      // Do more stuff here
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.