Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

Objective: When an Account is created in Salesforce I need to call a SAP webservice and create a customer in SAP.

What would be best approach?

  1. To call the SAP webservice from the Account trigger by calling a future method
  2. To create custom vf page, override the account creation and write the SAP webservice call logic in Save button.

Experts, please suggest me a best approach.

Thanks, Baskaran

share|improve this question

2 Answers 2

up vote 9 down vote accepted

Great question, the correct place to make callouts to synchronise with external systems is not initially that obvious, especially when there are so many ways in which users and/or developers can create data within Salesforce, such as Salesforce API's, Apex DML and Standard UI, you need to be sure to capture all these places or risk gaps in your external system.

Thoughts on Options 1 and 2

Option 2, only captures the UI side of creating an Account, i'd personally exclude that one immediately. Option 1, at the Apex Trigger level gets closer because your down at the data level, capturing the create event regardless of they way in which the user or developer attempted to insert the record. However as you have discovered you have to use asynchronous processing to get around the limitation of not being able to make callouts in Apex Triggers. This brings with it new vulnerabilities to consider, especially since @future methods are not easily tracked, making error handling and recovery quite critical here. Also when your performing large data loads there is a also a limit of 10 per Apex Trigger context.

Data Replication API and Apex Scheduler

I've recently discovered the Salesforce Replication API (which is a SOAP API) and its Apex equivalents. The Database.getUpdated method can used to obtain a list of records created within a certain time frame (also see Database.getDeleted).

Returns the list of individual records that have been updated for an sObject type within the specified start and end dates and times.

As long as you are not under pressure to make the synchronise realtime, you could use this API, to schedule an Apex job every day or every hour if needed. Then leverage Batch Apex to kick off a job to process the records, this will scale very well as it allows you to chunk the governor limits, such as those around the number of HTTP callouts (10 per Apex execution scope) that can be made per request or scope in Batch Apex terms. You can also better manage synchronisation errors, by collecting errors and emitting a report or log records at the end of the job.

Tweaked from the documentation linked above, to return the Accounts created in the last hour...

Database.GetUpdatedResult r =
 Database.getUpdated(
  'Account',
  Datetime.now().addHours(-1),
  Datetime.now());

The date range for the returned results is no more than 30 days previous to the day the call is executed.

NOTE: I would use a Custom Setting to record the last time the request was made, you can read more about the importance of retaining the data/time value returned by this API in the documentation. Also read the SOAP API version of the documentation i linked to, it covers stuff Salesforce don't mention in the Apex API documentation.

Thoughts on using Outbound Messaging via Workflow

The Salesforce Outbound Messaging facility allows you to make a call to an external web service. The main consideration here is that the web service must match the WSDL Salesforce generates for you as part of the setup. In other words it is not possible to use this with a custom web service, the web service must be built specifically for your outbound message from Salesforce. If you can provide the WSDL to a developer who can create such a custom end point this is a viable option, though pay close attention to the documentation in terms of volumes and performance. There looks to be some good resources to writing handlers here.

share|improve this answer
    
Thanks a lot, @Andrew. Is there a way to achieve this through OUtbound message. I am getting this error Delivery Failure Reason - Virtual Interface Method >notifications::soap.sforce.com/2005/09/outbound<; not supported. I have no clue of why this is happening. I am trying to push Account Id, Name, Account Number to SAP to the endpoint URL. Moreover, there is a need from client to synchronize both systems in real time... –  Baskaran S Feb 10 at 11:15
    
Thats a good point, i've updated my answer, the error your getting back from SAP (and I'm not expert on SAP servers) looks like its because it does not understand the SOAP request, which needs to map to one the server understands, typically this is done by the developer importing the supplied WSDL and writing some code (on the target server) to respond to requests. –  Andrew Fawcett Feb 10 at 11:25
    
Thanks again, @Andrew. –  Baskaran S Feb 10 at 11:32

I would strongly suggest using the first method. It works fine, and will also fire if Accounts are created through e.g. the API or any other means than the standard 'New' button.

With regard to the second method: in addition to being only one of the many options to create an Account, the second method also adds the overhead of (re)writing the Account Creation process in VF, which is unnecessary (unless you really want something custom or special in that process, but then I would still put the SAP call logic in a trigger, because then it will work for all Account creation use-cases)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.