how many times can you spot the letter "p" in:
q: avoiding recursion while updating trigger records i'm running into roadblocks everywhere with this particular task. my goal is simply to have a trigger do a get request on an external rest api service, get some data, and update the lead currently being worked on with said data during before insert/before update. 
here are some of the challenges i've run into so far: 


*

*i can't call the external web service synchronously from a trigger because it's not allowed. fine, i tried breaking up the logic into a new asynchronous trigger that works on after insert/after update.


*i can't run the update logic on after insert/after update because the lead object is read-only at that point.



my goal, at least to me, is very simple. i feel like there should be a simple solution to this. is there something i'm missing?
here's a simplified version of the trigger that already existed: 
trigger existingtrigger on lead (before insert, before update) 
{
  for (lead lead : system.trigger.new)
  {
    //here we do a bunch of updates to the lead based on data that already exists in salesforce. for example: 
    if (lead.special_field__c != null && lead.special_field__c != '' && system.trigger.isinsert)
    {
        if (lead.special_field__c .contains('a cat') && lead.cat_color__c == 'orange')
        {
            lead.cat_toy__c = 'mouse';
            lead.ginger__c = 'y';
        }
    }
  }
}

this is the new trigger i've created to handle the call to the third party api:
trigger assignvet on lead (after insert, after update) 
{    
    vethelper vethelper = new vethelper();

    for (lead lead : system.trigger.new)
    {
        try
        {
            vethelper.updatevet(lead.id);
        }
    }
}

finally, this is the class that has the async method that is supposed to update lead with data from the third party api: 
public with sharing class vethelper
{
    @future (callout=true)
    public static void updatevet(string leadid)
    {
       string url = 'http://192.168.0.1/lookup/' + leadid;
       httprequest reqdata = new httprequest();
       http http = new http();
       reqdata.setheader('content-type','application/json');
       reqdata.settimeout(20000); 
       reqdata.setendpoint(url);
       reqdata.setmethod('get');

       httpresponse res = http.send(reqdata);
       string response = res.getbody();

       dblead = [select vetname from  lead where id =: leadid limit 1];

       //let's pretend we can simply grab the values needed from the response object
      dblead.vetname = response.vetname;
      database.update(dblead, false);
    }
}

the code as it stands does not work because database.update causes both triggers to fire indefinitely. 

a: if you are worried about recursive calls, a boolean flag is a time tested strategy. just set one in your @future method and don't rerun that logic if the flag is set. using a handler pattern will greatly facilitate this strategy. below is a simple outline of what mine would look like.
handler
public class leadtriggerhandler
{
    public static boolean iscalledfromvethelper = false;

    final list<lead> newrecords;
    final map<id, lead> oldmap;
    public leadtriggerhandler(list<lead> newrecords, map<id, lead> oldmap)
    {
        this.newrecords = newrecords;
        this.oldmap = oldmap;
    }

    public void afterupdate()
    {
        if (!iscalledfromvethelper)
        {
            // vethelper logic
        }
        // other update logic
    }
}

callout helper
public class vethelper
{
    @future
    {
        leadtriggerhandler.iscalledfromvethelper = true;
        // existing logic
    }
}

trigger
trigger lead on lead (after insert, after update)
{
    leadtriggerhandler handle = new leadtriggerhandler(trigger.new, trigger.oldmap);
    if (trigger.isbefore)
    {
        // events
    }
    if (trigger.isafter)
    {
        if (trigger.isinsert) handle.afterinsert();
        if (trigger.isupdate) handle.afterupdate();
    }
}


user
The given text has 83 "p"s.
assistant