HTTP Callout from Triggers

  • I have a trigger on the Custom Object that calls a class. That class makes an HTTP GET request to a Web Service.

    However I get the following error:

    Callout from triggers are currently not supported.

    How can I get data to an external Web Service using Apex code?

    However i can use @future method but it can only be support void and this method cannot return results, i need to be able to send data to external ervice and receive acknowlegements from it.

    You seem to be aware of the limitations that exist. I suggest you acknowledge whatever needs acknowledging in the @future method and update the triggered object thereafter, you could have statuses on the object like "Reason for Callout", "Pending", "Success"/"Fail" allowing you to build logic around the current state of an object.

    @MartinPeters : can you please elaborate your thought?

    I don't know enough about your use case to give a detailed suggestion on what you should do. But basically, when you're firing the @future from a trigger you did id because some criteria on the object was met. You can at the same time set that the object is "pending" the result of the callout. The callout, once complete can query the object it originated and update it with appropriate success/failure based on what the endpoint answered.

  • Bob Buzzard

    Bob Buzzard Correct answer

    9 years ago

    Callouts cannot be made from triggers as that would hold up the database transaction until the callout completed, which can be up to 120 seconds from a limits perspective. This could obviously cause significant contention with other transactions and impact performance.

    The only way that you can execute a callout from a trigger is to schedule it to run asynchronously, for example by executing a method with the @future method as you have found. The key word here is asynchronously - you can't wait for a response from the callout as that would require the transaction to stall until it completes, which is the reason that synchronous callouts aren't allowed.

    The way that I've handled this kind of thing in the past is to have a field on the object that captures the response. I pass the id(s) of the record(s) that I am processing to the @future method. Then when the callout completes, the @future method can retrieve the record(s) from the database and update the field(s).

    If you are trying to return a response to the user (as part of a visualforce page maybe) you can still utilise this mechanism, you just have to poll the controller to check the object to see if a response has been received - I've used an actionpoller for this and provided the user with a 'checking' spinner to keep them (hopefully) interested.

    To add to Bob's response, if you are worried about validating the response, you can also write the id of the object to a custom log table object, have a trigger on that custom object call the @future method, and then update the fields you need to on the object tabel and also the log tabel with success/fail, and maybe alert the user if the update failed with any errors you got back from the web service/sf

License under CC-BY-SA with attribution

Content dated before 7/24/2021 11:53 AM