0

We have a REST service that gets data from external service to salesforce.

The data can be achieved using RestContext.request.requestBody.toString();

So I create an inner class to deserialize the request body into it.

My issue is that a param that is sent from the external service is a List of String, but if it's empty they sent an empty String ("").

So, on one hand, I need my inner class to have a List param, but on another, if it's empty - the param is equal to "" - it's not a List type anymore its a String, and its fails.

I know that one solution is to change the type it sent from empty String to empty array in the external service for example but it takes too long to get answers from them, and since it is urgent we decided to do it on our own.

another solution I thought about, is to substring the requestBody by the param name and check if it's an empty string or an array - and this solution could work, but I don't have one param, I have many.

So I wonder if there are other ways of doing this check, before the deserialization.

@HttpPost
    global static String getDataFromExternal(){

try{

   RootObject data = (RootObject) JSON.deserialize(RestContext.request.requestBody.toString(),RootObject.class);

}catch(Exception e){
    System.debug('e : ' + e.getMessage());
 }




    public class RootObject{
        List<String> shouldBeListParamA;
        List<String> shouldBeListParamB;
        List<String> shouldBeListParamC;
        String textParamA;
        String textParamB;
        String textParamC;

        public RootObject(){
          


        }
     }

}

And the Data received can be:

{"textParamA":"ABC","textParamB":"ABC","textParamC":"ABC","shouldBeListParamA":["ABC","CDE"],"shouldBeListParamB":"","shouldBeListParamC":"".......}

Clarifications:

The blank value - is for a param inside the body and not for the whole body.

means - a param type List<String> if it have data in it it will be like that:

"shouldBeListParamA":["ABC","CDE"]

but if this specific param received without data it will be empty, means "" instead of [] (empty array).

example:

"shouldBeListParamA":""

I need to create the type in my inner class - and I created it like that:

List<String> shouldBeListParamA;

but when its empty (just this param or other param with the same type) it will fail in the deserialization.

Many Thanks!

1 Answer 1

0

The thing you should be thinking about here is

  • What is causing my code to fail?
  • How do I detect that situation before my code would fail?

You already know the answer to that first question, when the request body is blank your attempt to deserialize will fail.

Now, how would you detect that?
The simplest approach would be to use String.isBlank()

Putting that together

// There are only a few instances where you truly need to use global visibility
// I do not believe this is one of them
@HttpPost
public static String getDataFromExternal(){
    // You may want to use the Safe Navigation Operator (?.) right before
    //   calling toString().
    // That depends on if Salesforce makes an empty request body null or the 
    //   empty string
    String jsonBody = RestContext.request.requestBody.toString();

    // It's generally a good idea to do checks for problematic conditions
    //   (empty strings, null variables, etc...) early.
    // Putting the undesired path into the IF block (as opposed to putting the
    //   main execution path into the IF block) can help with readability and
    //   maintenance
    if(String.isEmpty(jsonBody)){
        return 'Empty body';
    }

    // It's now reasonably safe to try deserialization
    // You could still run into issues if the string doesn't start with
    //   the OBJECT_START symbol ('{'), but you probably shouldn't worry
    //   about that until it starts happening.
    // If you do need to handle it, it's simple enough to just add another
    // if() or two before this point
    RootObject data = (RootObject)JSON.deserialize(jsonBody, RootObject.class);

    // Some other transformation so that you can return a String
    //   (as is required by your method signature)
}
1
  • Hi Derek, many thanks for your time. Maybe I was not clear enough, so I added a Clarification to my original question. The validation for the whole body is not here because I didn't meant to ask about it. I will much appreciate it if you can read the Clarifications section. Thanks again!
    – Salvation
    Apr 24, 2022 at 19:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .