GM - Save Hook Framework
This is not a Salesforce trigger it works only within the GridMate component.
Gridmate Save Hook is a customizable Apex extension point that allows you to inject logic before or after Salesforce record save operations (Insert or Update) while maintaining synchronous and asynchronous processing flows with external systems.

Rules for Save Hook and Callouts
1. Key Principles
For every N records processed, you must return exactly N
SaveHookResultobjects one per record.The order of results must exactly match the order of input records.
The framework uses positional mapping (Record n → Result n) to correctly associate results, ensuring accurate error reporting and user feedback.
2. Callout Execution Rules
Synchronous callouts are allowed only in the following contexts:
beforeInsertbeforeUpdate
At these points, the transaction has not yet been committed, making synchronous communication with external systems safe.
Synchronous callouts are prohibited in:
afterInsertafterUpdate
Use asynchronous methods instead:
@future(callout=true)for simple, deferred operations.Queueable Apex jobs (with callouts enabled) for more complex or queued background processing.
3. Before Events - Validation Stage
Use the beforeInsert and beforeUpdate events for record validation prior to saving data to Salesforce.
When a validation fails, return a SaveHookResult configured as follows:
isSuccess = truemarks the record as valid.isSuccess = falsemarks the record as invalid.statusCode(optional) provides an error code or identifier.messagegives a clear explanation of the validation issue.
For standard patterns and reusable logic, refer to the SaveHookManager managed class.
4. After Events - Post-Processing Stage
Use afterInsert and afterUpdate for post-commit operations such as:
Synchronizing with external systems.
Performing data enrichment.
Triggering asynchronous workflows or notifications.
All logic in this stage should be non-blocking and asynchronous, ensuring smooth execution without affecting the main transaction.
Never perform direct (synchronous) callouts in afterInsert or afterUpdate, as this will trigger Salesforce transaction errors and compromise data integrity.
Save Hook Setup
1. Framework instantiation
Here’s an example of the Save Hook apex Code:
To create a custom Save Hook, you must implement the gmpkg.SaveHookManager.ISaveHook global interface provided by the GridMate framework.
global class QuoteSaveHook implements gmpkg.SaveHookManager.ISaveHook {
global static List<gmpkg.SaveHookManager.SaveHookResult> call(String action, List<Quote> quotes) {
List<gmpkg.SaveHookManager.SaveHookResult> res = new List<gmpkg.SaveHookManager.SaveHookResult>();
switch on action {
when 'beforeUpdate' { // Synchronous call
... create HTTP request ...
HttpResponse response = new Http().send(req);
List<Object> apiResults = (List<Object>) JSON.deserializeUntyped(response.getBody());
for (Integer i = 0; i < quotes.size(); i++) {
Quote newQuote = quotes[i];
/*
this is the API result
for example if I receive :
{
"statusCode" : "400",
"messageAPI" : "error",
"success" : false,
"relatedFields" : ["Test__c"]
}
i will map this fields with the SaveHookResult
*/
Map<String, Object> apiResult = (Map<String, Object>) apiResults[i];
Booloean success = (Boolean) apiResult.get('success');
String statusCode = (String) apiResult.get('statusCode');
String message = (String) apiResult.get('messageAPI');
List<String> fields = (List<String>) apiResult.get('relatedFields');
if (success == false) {
gmpkg.SaveHookManager.SaveHookResult errorResult = new gmpkg.SaveHookManager.SaveHookResult(success, statusCode, message, fields);
res.add(errorResult);
} else {
gmpkg.SaveHookManager.SaveHookResult successResult = new gmpkg.SaveHookManager.SaveHookResult();
res.add(successResult);
}
}
}
}
return res;
}
}2. Save Hook Activation
Go to Setup.
Navigate to Custom Metadata Types.
Find Hook Config
Click Manage Records.
Create a new record
Fill in the required fields:
Label: A descriptive name (e.g., Quote SaveHook before Update).
SObject: The Salesforce object (e.g., Quote).
Hook Config Name: Unique developer name for the config (e.g., QuoteSaveHook).
Apex Class: The class implementing the hook business logic (e.g., QuoteSaveHook).
Context: The trigger context (e.g., beforeUpdate, beforeInsert, etc.).
Execution Order: A number that defines in which sequence hooks run (lower numbers run first).
Is Active: Set to true to activate the hook.
Save the record.
Last updated
Was this helpful?