+ Start a Discussion
justin_sfdcjustin_sfdc 

Apex Rest Callout Get Method

Hi there,
I am writing a webservice callout which is triggered on clicking a link in an Account detail page; Upon the click of the link, the code will go to the external system and get the record from the other system based on the account I clicked the link from and display in a VF page.
So far, I've got to the point where i could retrieve from the endpoint but I do not know how to put the condition based on which Account Id i click the link from?

<!-----Visualforce Page-------------->
<apex:page controller="GetRestfulExample" action="{!fetchData}" contentType="text/plain">
     {!response}
</apex:page>

<!---------Controller----------->
public class GetRestfulExample {
    private final String serviceEndpoint= 'http://headers.jsontest.com/';
    public String Response { get; set;}
    public String Headers { get; set; }
   
    public void fetchData() {
        getAndParse('GET');
    }

  public void getAndParse(String GET) {

    // Get the XML document from the external server
    Http http = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(serviceEndpoint);
   
    req.setMethod('GET');
    HttpResponse res = http.send(req);

    System.debug(res.getBody());
     this.response=res.getBody();
  }
}

Where can I put the condition to just display the fields for this account I am currently in?

Please throw me some ideas!

Thanks,
justin~sfdc
Best Answer chosen by justin_sfdc
Elie.RodrigueElie.Rodrigue
Here's a demo unmanaged package I created with your example : 
https://login.salesforce.com/packaging/installPackage.apexp?p0=04tG0000000L3O2
Just add the RestfulExample button in your account page layout.

Basically, when you call ApexPages.currentPage().getParameters().get, the value you pass to the get method is the part of the url you want to fetch. So if you send acct.cl_Num__c, then you need to open /apex/YourPage?acct.cl_Num__c=yourId.

So if you want your url to be ?id= then you need to do .get('id')

Also, make sure you add the endpoint url (without the parameters, only the domain part) to your allowed remote site.

The server receive exactly the url you sent him without a body (for get method). There's also some headers that you can check by changing the endpoint to http://headers.jsontest.com/ (but this doesnt display the parameters you send with your query).


All Answers

Elie.RodrigueElie.Rodrigue
You could either use a standard controller to get the id of the object, or you could send it as a parameter to you page (add ?myId=TheId)

If you add it as a parameter, you'll be able to call ApexPages.currentPage().getParameters().get('myId') to retrieve the actual id and send it to your rest call.
justin_sfdcjustin_sfdc

Hi Elie,

Thanks for the quick response. 
<!-----Visualforce Page-------------->
<apex:page standardcontroller="Account" extensionsGetRestfulExample" action="{!fetchData}" contentType="text/plain">
     {!response}
</apex:page>

<!---------Controller----------->
public class GetRestfulExample {
    private final String serviceEndpoint= 'http://headers.jsontest.com/';
    public String Response { get; set;}
    public String Headers { get; set; }
    private String Account acc;
   
    public GetRestfulExample(ApexPages.StandardController controller) {
        ApexPages.currentPage().getParameters().get('acc.id');
    }
    public void fetchData() {
        getAndParse('GET');
    }

  public void getAndParse(String GET) {

    // Get the XML document from the external server
    Http http = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(serviceEndpoint);
  
    req.setMethod('GET');
    HttpResponse res = http.send(req);

    System.debug(res.getBody());
     this.response=res.getBody();
  }
}

I have added the standard controller, and ApexPages.currentPage().getParameters().get('myId') in my controller constructor, but how do i pass it to the external system. I'm new at callouts so, I don't know what will be sent to this endpoint when we do the request.
I found out a blog where it has the endpoint set as this:
req.setEndpoint(serviceEndpoint+'?id='+acc.Id);

I did look into req.setBody('xxxxx'); which i thought could be used by the external system but i found out that setBody() does not help at all. 
Please let me know if any of the info I have is wrong and how could i proceed further. 


Thanks,
justin~sfdc

Elie.RodrigueElie.Rodrigue
Set body will mostly be used when doing http post, when you are sending data to the server.
When you do a get, you are actually polling data from the server and you want to add a parameter to that.

To validate your parameter work, you could try setting your endpoint to : http://md5.jsontest.com/
And then adding parameter ?text=' + acc.Id

the original part of the return value will be the parameter you sent.
try it out manually : 
http://md5.jsontest.com/?text=blah

Elie.RodrigueElie.Rodrigue
I also noticed : using the standard controller, you dont need to use the page parameters method. You could just do controller.getId() and it will return that id. You need to make sure you open the page through a visual force component or with the id= parameter in the url.

/apex/YourVFPage?id=YourAccountId

Here's your sample code, fixed : 
<!-----Visualforce Page-------------->
<apex:page controller="GetRestfulExample" action="{!fetchData}" contentType="text/plain">
     {!response}
</apex:page>

<!---------Controller----------->
public class GetRestfulExample {
    private final String serviceEndpoint= 'http://md5.jsontest.com/';
    public String Response { get; set;}
    public String Headers { get; set; }

  
    public GetRestfulExample() {
     
    }
    public void fetchData() {
        getAndParse(ApexPages.currentPage().getParameters().get('id'));
    }

  public void getAndParse(String objectId) {

    // Get the XML document from the external server
    Http http = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(serviceEndpoint+'?id='+objectId);
 
    req.setMethod('GET');
    HttpResponse res = http.send(req);

    System.debug(res.getBody());
     this.Response =res.getBody();
  }
}


Make sure you open the page with and id parameter. 

I hope it helps!
justin_sfdcjustin_sfdc
Hi Elie,

Thanks for the help. I appreciate it, this is for my general knowledge, now if I were to pass in the id value that is an external id in account object then;
private final Account acct;

public void fetchData() {
        getAndParse(ApexPages.currentPage().getParameters().get('acct.cl_Num__c'));
 }
public void getAndParse(String ext) {

.....
req.setEndpoint(serviceEndpoint+'?cl_Num__c='+ext);
....
}

If you dont mind telling me, when we send this request to the external system, what does the external system recieve from our end?
I am starting to understand slowly but wanted to make sure I am getting all well.

Thanks,
justin~sfdc
Elie.RodrigueElie.Rodrigue
Here's a demo unmanaged package I created with your example : 
https://login.salesforce.com/packaging/installPackage.apexp?p0=04tG0000000L3O2
Just add the RestfulExample button in your account page layout.

Basically, when you call ApexPages.currentPage().getParameters().get, the value you pass to the get method is the part of the url you want to fetch. So if you send acct.cl_Num__c, then you need to open /apex/YourPage?acct.cl_Num__c=yourId.

So if you want your url to be ?id= then you need to do .get('id')

Also, make sure you add the endpoint url (without the parameters, only the domain part) to your allowed remote site.

The server receive exactly the url you sent him without a body (for get method). There's also some headers that you can check by changing the endpoint to http://headers.jsontest.com/ (but this doesnt display the parameters you send with your query).


This was selected as the best answer
justin_sfdcjustin_sfdc

Hi Elie,
Great demo, i must say. 
In order to fetch the custom field in the endpoint, i made the following changes to the controller:

private Account acct;
public void fetchData() {
       acct=[Select id, CUNumber__c from Account where id=:ApexPages.currentPage().getParameters().get('id')];
       
       System.debug('==tst acct.Cl_Num is: '+ acct.Cl_Num__c);
        getAndParse(acct.Cl_Num__c);
      
    }

public void getAndParse(String ObjectId) {
...
}

Would that be ok?

Thanks,
justin~sfdc

Elie.RodrigueElie.Rodrigue
Sounds all good! Dont Forget to mark my answer if it solved your issue!
justin_sfdcjustin_sfdc

Sure ;) 
Will probably be in touch with you once putting this code into action. Currently waiting on the endpoint. Thanks!

Much Thanks,
Justin

justin_sfdcjustin_sfdc
Hi Elie,
I've got a question. Using the REST callout that we were working on, could i call another webservice in external system passing 3 parameters in it. How would i achieve it! Can that be done with the Rest Callout or do we have to invoke SOAP instead?

Please suggest me!

Thanks,
justin~sfdc
Elie.RodrigueElie.Rodrigue
You can add parameter to the url if you are still doing using a GET method.

?firstParam=Value1&secondParam=value2 and so on.
Make sure you url encode your values using EncodingUtil.urlEncode(value,'UTF-8')
Developer99Developer99
@Elie
 
                   i have a small task, i want to get the records from third party system and save it into salesforce. the fields which i want to get is account name,contact name,opportunity name and quotes this all records i want to get and save it into releated objects may i know how can i write a webservice by using rest. can you give me some sample code by using sample endpoint url.
Elie.RodrigueElie.Rodrigue
If you want to fetch the value from another system, you wont want to write a webservice, you'll want to consume one.

I do have a blog post that explain some of it : http://elierodrigue.com/2014/02/12/external-services-integration-some-possible-issues/

You just need to adapt it to your need.
justin_sfdcjustin_sfdc
Hi Elie,

Thanks for the quickie. I did go through your blog earlier too, very helpful. I like the way you have explained a lot of things; much in details.
Like you mentioned, I also thought that I would have to consume the webservice too, but I am a bit confused on if it can be done using REST or not. Well, I have not done this before (consuming the webservice) but I have a slight idea of how it is done like; I would add it to the org first and then would make the instance of that webservice class and then call the method whichever is required by passing in the parameters in it. But the way I am explaining is would be SOAP, isn't it! Not sure myself, lol!

Thanks,
justin~sfdc
Elie.RodrigueElie.Rodrigue
If its soap or rest doesnt matter, the logic / architechture of your solution stay the same.
Salesforce provide a WSDL to Apex tool that really help integrating "SOME" soap services but its really picky in what it let you do. 
With rest you have to build it from ground up with its much easier. You can get it going with a few line of code.
justin_sfdcjustin_sfdc
Hi Elie,

Have you worked on anything or have any idea regarding this new post I have:

https://developer.salesforce.com/forums/ForumsMain?id=906F0000000A3TmIAK

Thanks,
justin~sfdc
Huy NguyenHuy Nguyen
Hi all,

I try your code but it does not work . It also show error message . I already modified the link but it still does not work . Please help to checkUser-added image