Skip to content

Salesforce Integration

Mark a single-variant type with @SObject to treat it as a Salesforce SObject:

@SObject
type Account {
Account(Name: String)
}
let acc = Account(Name: "ACME")

Every @SObject type automatically gets an Id: Option<Id> field. This enables the insert-then-update pattern:

fn create_and_rename(name: String): Result<Void, DmlError> {
let acc = Account(Name: name)
let assert Ok(new_id) = Database.insert(acc)
let updated = Account(Name: "Updated: ${name}", Id: Some(new_id))
Database.update(updated)
}

All database operations return Result<T, DmlError>:

let result = Database.insert(Account(Name: "ACME"))
match result {
Ok(id) => debug "Created: ${id.toString()}",
Error(err) => debug "Failed: ${err.message}",
}
OperationSuccess type
Database.insert(sobj)Id
Database.update(sobj)Void
Database.delete(sobj)Void
Database.undelete(sobj)Void

Mark a function as callable from LWC with @AuraEnabled. It must return Result<T, AuraError>:

@AuraEnabled(cacheable: true)
fn getAccountName(id: String): Result<String, AuraError> {
// On Ok, the value is returned directly to LWC
// On Error, AuraHandledException is thrown automatically
Ok("ACME")
}

For LWC data transfer objects, annotate the type too:

@AuraEnabled
pub type AccountDto {
AccountDto(name: String, revenue: Decimal)
}

Vertex can call existing Apex code through extern declarations:

// Declare an Apex class as a Vertex type
extern type Messaging.SingleEmailMessage
// Declare an Apex constructor
extern new Messaging.SingleEmailMessage(): Messaging.SingleEmailMessage
// Declare an Apex instance method
extern method Messaging.SingleEmailMessage.setSubject(
self: Messaging.SingleEmailMessage,
subject: String,
): Void
// Use it
let msg = Messaging.SingleEmailMessage.new()
msg.setSubject("Hello from Vertex")

Control the Apex sharing modifier at the top of any .vtx file:

@WithoutSharing // or @WithSharing, @InheritedSharing
import lang.db
pub fn run(): Void { ... }

The default is with sharing. The safe Salesforce security default.