2

I have a Get Method which returns an invoice based on id. When I test this with Workbench I would like to have the following response:

{ 
"customerId": "1",
"addressId": "2018AA123",
"invoiceId": "00ec5a04a43c014aa9e8",
"invoiceType": "AdvancePayment",
"invoiceTypeLocalized": "Voorschot",
"invoiceDate": "2015-02-13T00:00:00",
"paymentDueDate": "2015-02-20T00:00:00",
"invoiceNumber": "157005888",
"startDate": "2015-03-01T00:00:00",
"endDate": "2015-04-01T00:00:00",
"periodDescription": "Maart 2015",
"amount": 100.10,
"vatAmount": 30.30,
"totalAmount": 100 
}

In my workbench I end up with the following response:

    "{\"attributes\":{\"type\":\"invoice__c\",
\"url\":\"/services/data/v43.0/sobjects/invoice__c/a000X000015LDn2QAA\"},
\"customerId__c\":\"1\",
\"addressId__c\":\"8212BJ154\",
\"Id\":\"a000X000015LDn2QAG\",
\"invoice ype__c\":\"AdvancePayment\",
\"invoice ypeLocalized__c\":\"Voorschot\",
\"invoiceDate__c\":\"2015-02-13\",
\"paymentDueDate__c\":\"2015-02-20\",
\"invoiceNumber__c\":\"157005888\",
\"startDate__c\":\"2015-03-01\",
\"endDate__c\":\"2015-04-01\",
\"periodDescription__c\":\"Maart 2015\",
\"amount__c\":100.10,
\"vatAmount__c\":30.30,
\"totalAmount__c\":100.00}"

How do I remove the attributes part and \ slashes. I tried the following for the slashes but this does not seem to work: return JSON.serialize(result[0]).replace('\','')

My Method:

@HttpGet
global static string getinvoiceById() {
    RestRequest request = RestContext.request;
    // grab the invoiceId from the end of the URL
    String invoiceId = request.requestURI.substring(request.requestURI.lastIndexOf('/')+1);
    List<Invoice__c> result =  [SELECT customerId__c , addressId__c , Id , invoiceType__c , invoiceTypeLocalized__c  , invoiceDate__c  ,
                           paymentDueDate__c , invoiceNumber__c  , startDate__c , endDate__c , periodDescription__c , amount__c , 
                           vatAmount__c , totalAmount__c FROM invoice__c
                    WHERE Id = :invoiceId];
    system.debug('result '+ result[0]);
    return JSON.serialize(result[0]);
}
  • It can be wiser to create wrapper class with given properties as on your first snippet, then create instance of that, and return in serialized way, rather then rely on replace, which may go wrong in case of bit more sophisticated data – kurunve Jun 23 '18 at 10:25
3

Your second response is what you get when an object is serialized to JSON twice; the first serialization produces the correct JSON and then the second serialization encodes that into a single JSON string.

So the general solution to this sort of problem is to work out where the extra serialization is happening and eliminate that rather than trying to manipulate the extra encoding after the fact. As you have not posted any code, it is not possible to provide a more specific answer.

PS

Now you have posted the code, this should fix the problem. The platform automatically does the serialization so you don't have to:

@HttpGet
global static Invoice__c getinvoiceById() {
    RestRequest request = RestContext.request;
    // grab the invoiceId from the end of the URL
    String invoiceId = request.requestURI.substring(request.requestURI.lastIndexOf('/')+1);
    List<Invoice__c> result =  [SELECT customerId__c , addressId__c , Id , invoiceType__c , invoiceTypeLocalized__c  , invoiceDate__c  ,
                           paymentDueDate__c , invoiceNumber__c  , startDate__c , endDate__c , periodDescription__c , amount__c , 
                           vatAmount__c , totalAmount__c FROM invoice__c
                    WHERE Id = :invoiceId];
    system.debug('result '+ result[0]);
    return result[0];
}

and if you do you get the unwelcome double serialization.

If you want to explicitly control the serialization, you can use this pattern where the method returns void and you set the response object directly:

@HttpGet
global static void getinvoiceById() {

    ...

    RestResponse res = RestContext.response;
    if (res == null) {
        res = new RestResponse();
        RestContext.response = res;
    }
    res.responseBody = Blob.valueOf(JSON.serialize(result[0]));
    res.statusCode = 200;
}

PPS

To change the names of the fields in the JSON you will need to go through a separate object e.g.:

    ...

    Map<SObjectField, String> mapping = new Map<SObjectField, String>{
        invoice__c.customerId__c => 'customerId',
        ...
    };
    Invoice__r r = result[0];
    Map<String, Object> m = new Map<String, Object>();
    for (SObjectField f : mapping.keySet()) {
        String t = mapping.get(f);
        m.put(t, r.get(f);
    }
    res.responseBody = Blob.valueOf(JSON.serialize(m));

    ...

If the field name mapping can be done using an algorithm e.g. drop the __c and make the first letter lowercase then you could build mapping that way.

  • I added the method to be more specific – Thomas Jun 23 '18 at 10:32
  • I am new to this serialisation part so bear with me, in this case I end up with the Saleforce fields. I want to return the external fields so customerId__c should be customerId do I need to write a method for this?. Ps I tried the last part but end up with: Illegal assignment from string to blob – Thomas Jun 23 '18 at 10:52
  • @Thomas My bad on the Blob thing - corrected now. I'll add a PPS on changing the names. – Keith C Jun 23 '18 at 10:57

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.