1

I have found a lot of different examples of this, but I'm still having troubles accomplishing this. Here is the webservice which is working:

//WORKING Webservice in target org

@RestResource(urlMapping='/v1/workwebservice/*')
global with sharing class REST_WorkService_V1 {

@HttpPost
global static PostResponseWrapper doPost(RequestWrapper rqst) {
    RestRequest req = RestContext.request;
    RestResponse res = RestContext.response;
    PostResponseWrapper response = new PostResponseWrapper();
    System.debug('**response : ' + response); 

    try {

        insert rqst.workList;
        response.workList = rqst.workList;

        response.status = 'Success';
        response.message = 'Your Work records have been created successfully';
    }
    catch(Exception exc) {
        res.StatusCode = 500;
        response.workList = null;
        response.status = 'Error';
        response.message = 'Sorry, your request failed with the following error: ' + exc.getMessage();
    }

    return response;
}

global class RequestWrapper {
    List<Work__c> workList;
}

global class PostResponseWrapper {
    List<Work__c> workList;
    String status;
    String message;

    public PostResponseWrapper(){

    }
}   
}

Here is the sample JSON request that will work :

//WORKING JSON request body string
{
  "rqst": {
    "workList": [
      {
        "Name": "TestWorkItem",
        "Sprint__c": "a09f100000Hw0iM",
        "Description__c": "This is a description",
        "isTest__c": 1
      },
      {
        "Name": "TestWorkItem2",
        "Sprint__c": "a09f100000Hw0iM",
        "Description__c": "2nd description",
        "isTest__c": 1
      },
      {
        "Name": "TestWorkItem3",
        "Sprint__c": "a09f100000Hw0iM",
        "Description__c": "del 3 description",
        "isTest__c": 1
      }
    ]
  }
}

However, I am having a problem knowing how to create this JSON string from data in my org within a custom Work__c object. I want to serialize the data so that it exactly matches the above sample request.

This code exists inside a batch class that is going to periodically pass records from one Salesforce org to another . So, I have a list of Work__c records that need to be serialized into above JSON format and passed in a callout.

// I am passing in the List<Work__c> into my method

public void actualCallout(String inputString, List<Work__c> scopeList) {

// If I directly serialize the Work__c list:

String jsonSer = JSON.serialize(scopeList);
            System.debug(jsonSer);

// Here is the prettified JSON request : 

[
  {
    "attributes": {
      "type": "Work__c",
      "url": "/services/data/v44.0/sobjects/Work__c/a390H00000211xcQAA"
    },
    "Id": "a390H00000211xcQAA",
    "Due_Formula__c": -2,
    "DueDate__c": "2019-01-02",
    "Name": "Feature - at end of sprint, batch should roll over all those that are not comple"
  },
  {
    "attributes": {
      "type": "Work__c",
      "url": "/services/data/v44.0/sobjects/Work__c/a390H00000211xhQAA"
    },
    "Id": "a390H00000211xhQAA",
    "Due_Formula__c": -2,
    "DueDate__c": "2019-01-02",
    "Name": "Enable Field History tracking for Sprint"
  }
]

So, I am wanting to use a Wrapper class to send "rqst" as the outer-most JSON level from my Work__c custom object.

//
// Generated by JSON2Apex http://json2apex.herokuapp.com/
//

//NOT WORKING

public class WorkRequest {

public Rqst rqst;

public class WorkList {
    public String Name {get;set;}
    public String Sprint {get;set;}//Sprint__c;
    public String Description {get;set;}//Description__c;
    public Boolean isTest {get;set;}//isTest__c;

    public WorkList(String n, String spr, String des, Boolean t) {
        Name = n;
        Sprint = spr;
        Description = des;
        isTest = t;
    }
}

public class Rqst {
    public List<WorkList> workList;

    public Rqst() {
        this.workList = workList;
    }
}

public WorkRequest() {
        this.rqst = Rqst;
    }   
}

I am not understanding how the "Sprint__c" will be assigned from the parameter for "Sprint" ( I can't save it with __c : "Invalid character in identifier: Sprint__c (Line: 11, Column: 17). I also do not understand how to add my specific "Work__c" records to -- public List workList

Thanks in advance for your help. This is a simple problem that I do not know how to solve, but hopefully it can help others if you can look at my specific code and suggest how to fix it.

Sources :

  • You would need to use the "Explicit parsing" option in JSON2Apex to get a class you could use in an Apex class, or you could create custom objects that replicate these objects, or use JSON.deserializeUntyped and parse the results directly. Any way you look at it, it's going to require a bit more work than you initially thought. – sfdcfox Jan 4 at 7:37
  • @sfdcfox Sorry, I wasn't clear about what I am trying to do. I am trying to send out data that exists in my org in a custom object named "Work__c" which I am sending from a batch class periodically from 1 SF org to a 2nd SF org. I've updated the post above. – James Green Jan 5 at 0:53
1

You can do the following workaround to make this happen. First, generate the wrapper class from the JSON (it will have those __c). Then replace the __c to _c to Save the wrapper class (WorkRequest).

Now you can populate the data in the wrapper class, Serialize it, get the raw JSON String and replace all the _c to __c before sending to the request as below. By doing this you can send the JSON as required by your web service.

String rqString = System.JSON.serialize(wr);
System.debug(rqString);
rqString = rqString.replaceAll('_c', '__c');
System.debug(rqString);

Wrapper Class

//
// Generated by JSON2Apex http://json2apex.herokuapp.com/
//

public class WorkRequest {

    public Rqst rqst;

    public class WorkList {
        public String Name;
        public String Sprint_c;
        public String Description_c;
        public Integer isTest_c;
    }

    public class Rqst {
        public List<WorkList> workList;
    }


    public static WorkRequest parse(String json) {
        return (WorkRequest) System.JSON.deserialize(json, WorkRequest.class);
    }
}
  • Thank you! Do you still recommend this approach after I have given the above clarification in post, or can you give me something more specific. I am not sure how to cast the data in the wrapper class, and perhaps my wrapper class is wrong. – James Green Jan 5 at 0:49

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.