function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Pete1234Pete1234 

Getting started with JSON

Hi all,

 

Sorry for the newbie questions, but I've been hunting around for some information on how to use JSON in Salesforce and found some good resources however I've still got some questions about how Salesforce can receive a JSON feed from another system and process the results accordingly.

 

The scenario is Salesforce will be receiving a regular feed of master data (finance accounts) from an ERP system. Specifically the quetions I have are:

 

  1. I've found examples that show how to serialise and deserialise JSON messages, however how is the JSON Apex Class exposed so the sending system can deliver it's message?
  2. How is the request authenticated?
  3. How do you map the JSON message onto a Custom Object? Is it simply a case of looping through the message once it's deserialised and insert / upserting into the object?

Any help or pointers gratefully received.

logontokartiklogontokartik

Please find my answers below

 

1. You need to come up with what Integration method you are going to use, if you want to write a Custom REST Webservice or use Standard Salesforce REST Services?

     a. If you write custom webservice, then the contract (JSON Structure) is in your control, the sending system can send it in any format and at Salesforce side you need to build the right Apex Class to deserialize the message sent.  http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_rest_code_sample_basic.htm

     b. If you decide to go with Salesforce Standard REST Services, the sending system needs to send the data in exact format the Object is built in Salesforce. http://www.salesforce.com/us/developer/docs/api_rest/api_rest.pdf

 

2. For any authentication to salesforce, you have to use OAuth 2.0 http://wiki.developerforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com

 

3. You can use JSON.deserialize to map the JSON to the Custom Class you built or to the Salesforce Object.

 

Hope this helps.

Pete1234Pete1234

Thanks for the help and the confirmation I was going in the right direction.

 

I've almost got something working from a testing perspective, basically a Visualforce Page that serialises some test data and sends to the REST Apex class. However the message that gets returned is:

 

[{"message":"JSON request body must be an object at [line:1, column:2]","errorCode":"JSON_PARSER_ERROR"}]

 

 

public class sapaccount {
		
        String soldto;
        String customername;
        
        public SAPAccount( String a, String b ) {
        	
            soldto = a;
            customername = b;
        
        }
    
    }

	public Pagereference postResult(){
		
		// Prepare some test data...
		sapaccount sap1 = new sapaccount('0000000001','Customer 1');
		sapaccount sap2 = new sapaccount('0000000002','Customer 2');
		
		List<sapaccount> sapaccounts = new List<sapaccount>();
        sapaccounts.add( sap1 );
        sapaccounts.add( sap2 );
        
        // Serialize the list of sapaccount objects.
        //String jsonsapaccounts = JSON.serializePretty( sapaccounts );
        String jsonsapaccounts = JSON.serializePretty( sapaccounts );

		HttpRequest req = new HttpRequest();
		req.setMethod('POST');
		req.setHeader('content-type', 'application/json');
		req.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId() );
		req.setEndpoint( 'https://cs13.salesforce.com/services/apexrest/SAP_Account__c' );
		req.setBody( jsonsapaccounts );
        System.debug( '##### Serialized list of sapaccounts into JSON format: ' + req.getBody() );

		Http http = new Http();
		HTTPResponse resp = http.send( req );
		myresponse = resp.getBody();

		return null;
	
	}

 

 

My REST class is below:

@RestResource(urlMapping='/SAP_Account__c/*')
global with sharing class SAPAccountREST {

	@HttpPost 
	global static SAPAccount[] postRestMethod( SAPAccount[] jsonsapaccounts ){
		
    	return jsonsapaccounts;
    	//return 'Hi, You have invoked getservice1 created using Apex Rest and exposed using REST API';
    	
	}

	global class SAPAccount {
		
        global String soldto { get; set; }
        global String customername { get; set; }
        
    }
	
	
}

 

Can anyone point me in the right direction of where I'm going wrong? Basically I'm trying to avoid using curl... 

logontokartiklogontokartik

Looks almost right to me except when you use APEX Rest Services, the only methods you can use are doGET, doPUT, doPOST, doDELETE, and you cannot have any arguments for the methods. Everything that you send in the body can be retrieved from RESTRequest parameter. Try the below

 

@RestResource(urlMapping='/SAP_Account__c/*')
global with sharing class SAPAccountREST {

	@HttpPost 
	global static SAPAccount[] doPost(){
	String postBody = RestRequest.requestBody.toString();
       List<SAPAccount> sapaccts = (List<SAPAccount>)JSON.deserialize(postBody,List<SAPAccount>.class);
	
return sapaccts;
    	//return 'Hi, You have invoked getservice1 created using Apex Rest and exposed using REST API';
    	
	}

	global class SAPAccount {
		
        global String soldto { get; set; }
        global String customername { get; set; }
        
    }
	
	
}

 

RocketRocket

Hi karthik,

 

I was looking at your code and I hope you can help me with my doubt.you have explained how one can post data from outside to salesforce using  apex rest base classes.

 

How can we use external id's here?.I just want to make suire that when same record has been fetched from outside salesforce and update has been made to the record then what code we have to write in our apex rest classes to ensure that record in salesforce only gets updated not inserted.

 

I have understanding of the external id's but doen't understand how we can use that in our code.

Any ideas will be highly appreciated.

Thanks

logontokartiklogontokartik

Sorry for delayed response,

You can use upsert <objectName> <External Id field name> and the DML operation will take care of making sure if the record exists it updates it otherwise inserts it.

 

For more info, please follow the link

 

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_upsert.htm

Ruwantha  LankathilakaRuwantha Lankathilaka
Your json is wrong the json MUST have the parameter key

See the following example 

@RestResource(urlMapping='/SAP_Account__c/*')
global with sharing class SAPAccountREST {

	@HttpPost 
	global static SAPAccount[] postRestMethod( SAPAccount[] jsonsapaccounts ){
		
    	return jsonsapaccounts;
    	//return 'Hi, You have invoked getservice1 created using Apex Rest and exposed using REST API';
    	
	}

	global class SAPAccount {
		
        global String soldto { get; set; }
        global String customername { get; set; }
        
    }
	
	
}

Above class must have the json with following format

{
  "jsonsapaccounts": [
    {
      "soldto": "ssss",
      "customername": "eeee"
    }
  ]
}


Quddus Ololade 4Quddus Ololade 4
Hi, I am facing issues similar to this while getting the request from different system , Wanted to understand one thing in rest service the .setbody always has to be string so how come in the restmethod for post it can be an object in the above example.
I have the query at the bottom of this question: https://developer.salesforce.com/forums/ForumsMain?id=9060G0000005XPPQA2