I am working on an Apex Rest Resource to provide an integration from our scm provider's web hooks. The request sent by the scm provider is in JSON format so I have created an Apex class to mirror that object structure.

The problem I am running into is that the request contains a property named commit. Because commit is a reserved keyword in apex, I cannot create a property with this name. If I had any control over the deserialization I could use commit_x with a replace beforehand. However, I have no control over the deserialization from an apex @ResetResource class.

How can I handle the reserved keyword commit in the request? Apex must have some mechanism for this otherwise it would mean that you can never create a rest api for any service that uses a reserved keyword in its data, which would be absurd.




Sadly, this means that you'll need to use either a JSONParser or a generic Object that you can get from JSON.deserializeUntyped.

In summary, that means you'll ultimately need to do a bit more heavy lifting than if there were no reserved keywords. I prefer to use JSON.deserializeUntyped, personally, but this means you'll need to know what kind of data is coming in. The initial return value might be a List<Object> or a Map<String, Object>, which you can test for using instanceOf or a simple try-catch block. From there, you can recursively examine each Object to see if it is a list or a map, and parse the results.

Example Code

@HttpPost global static void handlePostAction() {
     Object jsonObj = JSON.deserializeUntyped(RestContext.request.requestBody);
     // Do something with jsonObj, which may be a list or map
  • 1
    aah, 5 seconds earlier. One of the tricky solutions may be using res.replace("\"commit\"","\"commit_c\""); – kurunve Feb 4 '16 at 19:49
  • 1
    So I am very familiar with how to do this from the context of an Apex class. However, my question is specific to a @RestResource class. Salesforce does the JSON deserialization before my apex has a chance to run. In addition, apex does not allow the use of the generic Object within the parameters. Maybe I am missing something but I do not believe I have any control over the deserialization, so the approach above will not work – dsharrison Feb 4 '16 at 20:11
  • 1
    @D.S. Actually, don't place any parameters on your function, and you get access to the raw data via RestContext.request.requestBody (it's a static varaible). See more info at RestRequest class. – sfdcfox Feb 4 '16 at 22:29
  • Fantastic, I thought that the HttpPost method required the use of method parameters and that the RestContext was only available for HttpGet. This opens me up to do my own deserialization. Thanks! – dsharrison Feb 4 '16 at 23:15

So the way I handle this is to replace the keyword before de-serialising the request into the Apex object.

Something like this:

String requestBodyStringSafe = requestBodyString.replaceAll('\"commit\":', '\"commit_x\":');

Then use that string instead of the request body to create your Apex object.

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.