The key word in the question is elegantly; I'm an experienced developer familiar with the mechanics of asynchronous programming, REST APIs, database triggers, programming idioms and design patterns. However I'm rather new to Salesforce.
I have a working solution using the Tell Don't Ask idiom but it feels clumsy and also rather intractable to improvement. Unfortunately corporate policy prevents me sharing the code in detail so I will need to provide a detailed exposition and my reference sources I've used to construct it. If you need elaboration I will expand any areas as much as possible.
- Triggers on creation or update of records from salesforce, these are quite focused with regard to the single responsibility principle.
- Call a class/module to prepare json from data in
- Call a REST client class/module with the json.
- REST client module
- Makes an asynchronous authorisation call wrapped with using
- On successful REST authorisation this makes a self call to another method to submit the json data.
- The data is sent by HTTP POST (for create) & HTTP PUT (for update) to an idempotent compliant service.
- The service responds with success or failure
- The service call is timely but not immediate, O(500-800ms).
- When successful it returns a correlation ID.
- The REST module calls a seperate update class/module to update the original salesforce record with the correlation ID.
- I need to carry around several pieces of disparate data, between the modules, the Salesforce record IDs, the third party system record Id and the returned event correlation ID.
- I need to carry a pair of flags in the record to prevent the correlation ID update from looping back into the trigger causing another redundant call to the external system.
- The slight delay caused by the asynchronous call means the record on screen after the trigger is already out of date.
- Callout limits severely inhibit my test cases, setting up prerequisite test data and validating the expected data, blow the limits.