Me

 

Apex data transforms with DataWeave

  • What, Why, and when
  • Tooling
  • Examples
  • Benefits & Limitations
  • The future

DataWhat

  • Data Transformation Framework
  • Functional
  • Packageable
  • In Beta - GA in Summer
    (safe harbour)

DataWhy & DataWhen

  • Reduced amount of code
  • Eases complex transformation tasks
    e.g. sObject ⇒XML
  • Highly scaleable
  • Useful for Mulesoft

Let's dive in


						%dw 2.0
						output application/csv
						---
						[
							{"Name": "CzechDreamin", "City": "Prague"},
							{"Name": "London's Calling", "City": "London"}
						]
					

							Name,City
							CzechDreamin,Prague
							London's Calling,London						
						

Let's go a bit further


						%dw 2.0
						var data = [
							{"Name": "CzechDreamin", "City": "Prague"},
							{"Name": "London's Calling", "City": "London"}
						]
						output application/json
						---
						{
							"Names": data.Name,
							"Cities": data.City
						}
					

Let's go a bit further

DataWeave Script


							%dw 2.0
							var data = [
								{"Name": "CzechDreamin", ...},
								{"Name": "London's Calling", ...}
							]
							output application/json
							---
							{
								"Names": data.Name,
								"Cities": data.City
							}
						

Output


								{
									"Names": [
										"CzechDreamin",
										"London's Calling"
									],
									"Cities": [
										"Prague",
										"London"
									]
								}					
							

You said somthing about be Apex


						%dw 2.0
						input records application/csv
						output application/apex
						---
						records map(record) -> {
							FirstName: record.fname,
							LastName: record.lname,
							Email: record.email
						} as Object {class: "Contact"}
					

Apex... finally


						// CSV data for Contacts
						String scriptName = 'csvToContacts';
						String inCsv = 'fname,lname,email\nCodey,"The Bear",codey@salesforce.com';

						DataWeave.Script dwscript = DataWeave.Script.createScript(scriptName);
						DataWeave.Result dwresult = dwscript.execute(
							new Map<String, Object>{'records' => inCsv}
						);

						List<Contact> results = (List<Contact>)dwresult.getValue();
						System.debug(results[0]);
					

Let's take things further

What we have

  • Account
  • Invoices

 

What we want

  • XML Output
  • Date formatting
  • Defaults

								<?xml version='1.0' encoding='UTF-8'?>
								<REPORT>
									<VENDOR_NAME ID="Id">Name</VENDOR_NAME>
									<INVOICES>
										<INVOICE>
										<INVOICE_NUM ID="Id">Name</INVOICE_NUM>
										<ENT_AMT>Amount</ENT_AMT>
										<INVOICE_DATE>dd-MMM-yy</INVOICE_DATE>
										<PAYMENT_TERMS>default = 30</PAYMENT_TERMS>
										</INVOICE>

										<INVOICE>
										...
										</INVOICE>
									</INVOICES>
								</REPORT>
							

Our Records

A simple web service


						@HttpGet
						global static void doGet() {
							...
							
							List<DW_Invoice__c> invoices = [SELECT ...];
							Account acc = invoices[0].Account__r;

							String scriptName = 'invoiceToXml';
							DataWeave.Script dwscript = DataWeave.Script.createScript(scriptName);
							DataWeave.Result dwresult = dwscript.execute(new Map<String, Object>{
								'invoices' => invoices, 'account' => acc
							});

							RestResponse res = RestContext.response;
							res.responseBody = Blob.valueOf(dwresult.getValueAsString());
						}
					

						<?xml version='1.0' encoding='UTF-8'?>
						<REPORT>
							<VENDOR_NAME ID="Id">Name</VENDOR_NAME>
							<INVOICES>
								<INVOICE>
								<INVOICE_NUM ID="Id">Name</INVOICE_NUM>
								<ENT_AMT>Amount</ENT_AMT>
								<INVOICE_DATE>dd-MMM-yy</INVOICE_DATE>
								<PAYMENT_TERMS>default = 30</PAYMENT_TERMS>
								</INVOICE>

								<INVOICE>
								...
								</INVOICE>
							</INVOICES>
						</REPORT>
					

						input invoices application/apex
						input account application/apex
						var defaultPaymentTerms = 30
						---
						REPORT: {
							VENDOR_NAME @(ID: account.Id): account.Name,
							INVOICES:
								INVOICE:
									invoices map(record) -> {
										INVOICE_NUM @(ID: record.Id): record.Name,
										ENT_AMT: record.Entered_Amount__c,
										INVOICE_DATE : (record.Invoice_Date__c >> "UTC") 
										  as String {format: "dd-MMM-yy"},
										PAYMENT_TERMS: record.Payment_Terms__c default defaultPaymentTerms
									}
						}
					

There it is, but what else do I need to know

Limitations

  • Performance
  • No Excel Type

But... the Benefits

  • A LOT less Apex
  • Increased power
  • Reduced complexity
  • Highly scaleable

The Future

Roadmap

  • GA (fingers crossed)
  • Performance

Next Steps

  • Tutorials & Challenges
  • Try in the playground, or VS Code

Resources

Any questions?