+ Start a Discussion
Marc C.Marc C. 

REST Implementation Returns Invalid JSON

Consider the following apex class:
@RestResource(urlMapping='/test/*')
global class TestRest {
   @HttpGet
   global static string doGet() {
      return '{"a":"b"}';
   }
}

This should produce:
{"a":"b"}
which is valid JSON. If you do system.debug it comes out exactly as expected.
But when you actually call the service via HTTP it produces literally:
"{\"a\":\"b\"}"
which isn't valid JSON at all.
I'm sure this is a bug because it's somehow encoding the result as a Java string which no JSON parser can understand.
Best Answer chosen by Admin (Salesforce Developers) 
Marc C.Marc C.

OK, finally gottit - just return an sObject (I was returning a string) and SF does the serialization for you:

@RestResource(urlMapping='/account/v1/*')
global class AccountRest {
    @HttpGet
    global static sObject doGet() {
        RestRequest req1 = RestContext.request;
        Id AccountID = req1.params.get('id');
        try {
            Account acc = [SELECT Id, Name, Type FROM Account WHERE Id = :AccountId LIMIT 1];
            return acc;
        } catch (exception e) {
            return null;
        }
    }
}
GET /services/apexrest/account/v1?id=001L0000004QN4z HTTP/1.1
User-Agent: Fiddler
Authorization: OAuth *******
Host: cs8.salesforce.com
Accept: application/json


HTTP/1.1 200 OK
Server: 
Content-Type: application/json; charset=UTF-8
Date: Thu, 29 Mar 2012 07:33:35 GMT
Content-Length: 146

{"attributes":{"type":"Account","url":"/services/data/v24.0/sobjects/Account/001L0000004QN4zIAG"},"Name":"Test Company","Id":"001L0000004QN4zIAG"}

All Answers

JitendraJitendra

Hi Marc,

I think you are storing the JSON result in String and then try to print the string, as string cannot have double quotes it appends the escape sequence character to it. If you are requesting in Apex class then Serialize the response to any class, it works flawless. Or if i am missing your scenario, please explain it.

 

Marc C.Marc C.

Hi Jitendra

It's literally returning 15 bytes instead of 9 so it's not just a display issue. Try look at the response in fiddler and you'll see it's not valid JSON. Basically if your used eval() in JavaScript to parse the REST result you'd get a string and not an object. This string would then have to be evalled again. The code I posted is simple but the same problem occurs if you use JSON.serialize() to serialize an account object. Would appeciate it if you could try it out your end.

Cheers

Marc

Marc C.Marc C.

I can confirm that standard SF REST services return valid JSON:
GET https://cs9.salesforce.com/services/data/v24.0/query/?q=SELECT%20Id,%20Name%20FROM%20Account%20LIMIT%201 HTTP/1.1
User-Agent: Fiddler
Authorization: OAuth *****
Host: cs9.salesforce.com

Returns
{"totalSize":1,"done":true,"records":[{"attributes":{"type":"Account","url":"/services/data/v24.0/sobjects/Account/001K000000B5DTjIAN"},"Id":"001K000000B5DTjIAN","Name":"New Test Cust"}]}

Fiddler parses it as valid JSON.

Marc C.Marc C.

OK, finally gottit - just return an sObject (I was returning a string) and SF does the serialization for you:

@RestResource(urlMapping='/account/v1/*')
global class AccountRest {
    @HttpGet
    global static sObject doGet() {
        RestRequest req1 = RestContext.request;
        Id AccountID = req1.params.get('id');
        try {
            Account acc = [SELECT Id, Name, Type FROM Account WHERE Id = :AccountId LIMIT 1];
            return acc;
        } catch (exception e) {
            return null;
        }
    }
}
GET /services/apexrest/account/v1?id=001L0000004QN4z HTTP/1.1
User-Agent: Fiddler
Authorization: OAuth *******
Host: cs8.salesforce.com
Accept: application/json


HTTP/1.1 200 OK
Server: 
Content-Type: application/json; charset=UTF-8
Date: Thu, 29 Mar 2012 07:33:35 GMT
Content-Length: 146

{"attributes":{"type":"Account","url":"/services/data/v24.0/sobjects/Account/001L0000004QN4zIAG"},"Name":"Test Company","Id":"001L0000004QN4zIAG"}
This was selected as the best answer