Wednesday, July 6, 2022

Reviewing and evaluating different integration patterns available within Salesforce

Approach

Data integration is used to synchronize data between two or more systems. It can be described as combining data from different sources into one cohesive view. The outcome of data integration should be trusted data that is meaningful and valuable to the business process.

Process integration combines business processes from two or more systems to complete a given process task. Process integration requires more robust systems and extended transaction timing to complete the integration.

Virtual integration is used to search, report, and update data in one or more external systems. This type of integration requires real-time access and retrieval of data from the source system.

Timing

Synchronous communication is when one system sends a request to another system and must wait for the receiving system to respond. Synchronous timing is generally expected in real time.

Asynchronous communication occurs when one system sends a request to another system and does not wait for the receiving system to respond. Asynchronous timing does not require real-time communications.

Source, Target, and Direction

Each integration must have a source or sending system and a target or receiving system. Direction can be more than a pointer. Integration can be unidirectional (one-way), bidirectional (two-way), omni-directional (broadcast or one-to-many), etc.

Calling Mechanism

Salesforce has several ways to initiate integrations, including triggers, controllers, workflows, processes, flows, platform events, and batch processes.

  • Apex callouts
  • Bulk API
  • Canvas
  • Chatter REST API
  • Email
  • External objects
  • Metadata API
  • Middleware
  • Outbound messages
  • Platform event
  • Push notifications
  • RESTful API
  • SOAP-based API
  • Streaming API
  • Tooling API

Error Handling and Recovery

Integration patterns react to errors and perform rollbacks in different ways. The approach used to manage error handling and recovery is critical in selecting and managing a given integration pattern.

Idempotent Design Considerations

An operation is idempotent when it produces the same result whether you execute it once or multiple times. The most common method of creating an idempotent receiver is to search for and track duplicates based on unique message identifiers sent by the consumer.

Security Consideration

Salesforce recommends two-way SSL and appropriate firewall mechanisms to maintain the confidentiality, integrity, and availability of integration requests.

State Management

The use of primary and unique foreign keys allows different systems to maintain the state of data synchronization. If Salesforce is the master, the remote system must store the Salesforce ID, and if the remote system is the master, Salesforce must store the unique remote ID.

Integration patterns supported by Salesforce.

Request and Reply: As a requesting system, Salesforce invokes a remote system call for data and waits for the integration process to complete.

Fire and Forget: As a requesting system, Salesforce invokes a remote system call for data, is acknowledged by the remote system, and does not wait to complete the integration process.

Batch Data Synchronization: Either Salesforce or a remote system invokes a batch data call or published event to synchronize data in either direction using a third-party ETL solution or Salesforce Change Data Capture.

Remote Call-In: As a target system, Salesforce receives a remote system call to create, retrieve, update, or delete data by a remote system.

UI Update Based on Data Changes: As a requesting system, Salesforce listens for a PushTopic (CometD protocol) and updates the user interface (UI) to represent the received change.

Data Virtualization: As a requesting system, Salesforce establishes a virtual connection using Salesforce Connect to create an external object to access real-time data.

Share This:    Facebook Twitter

Monday, December 13, 2021

Javascript: Working with Arrays using Asynchronous operations

Let’s say we have a list of names. For each name, we want to make an API call and get some information, and then keep a new list with this collection of information. A typical approach may look like this.

Refactoring to using map or forEach is not that straightforward here. The callbacks provided to map or forEach (or any of the array-methods) are not awaited, so we have no way of knowing when the full collection of information is done and ready to use. However, there is still a way we can write this in a nice way. Using the Promise.all method.

Awesome! Now, map returns a list of promises, and the Promise.all method takes a list of promises and resolves them in parallel. Not only did the code become much more nice and clean - but we also benefit from the fact that the promises are not resolved sequentially, which speeds up the process and increases performance.

Share This:    Facebook Twitter

Javascript: sort() and Array destructuring

Take a look at the code below.

At first glance, this looks good. We’re not using let, and we’re not mutating on the original array using something like push. But take a look at the console.log statement. It turns out that the sort method does not create a copy of the original array. Instead, it both mutates on the original array and returns its own array from the method call.

And there are a handful of old Array-methods that do this. Be careful with push, shift, unshift, pop, reverse, splice, sort, and fill. Fortunately, most often we can simply avoid calling these methods at all, to stay out of trouble.

However, there are cases, like using sort, where we have to use a method that mutates the original array, in lack of better options. Array destructuring to the rescue! Whenever these occasions arise, make sure to manually copy the array first, before performing an operation on it. It’s as simple as this.

That [...grades] makes the entire difference.

Share This:    Facebook Twitter

Javascript: Pass arguments as an object

Say we have a function, createUser, which requires four arguments in order to create a new user (by calling some API).

When looking at the function signature itself, things seem to make pretty good sense. But how about when we call it?

It’s pretty unclear what the arguments mean, right? Especially the last two booleans. I would have to go to the implementation to look it up. Instead, we can wrap the arguments in an object.

Thanks to ES6 object destructuring, we can do this easily by simply adding curly brackets around the arguments. Now, whenever we call createUser, we pass an object as a single argument with the required values as properties instead.

See how nice that reads out now. We’re no longer in doubt what those booleans mean. There’s another version of this that I’ve seen very often: Passing optional arguments as an options object. The idea is to pass 1-2 essential arguments and then pass the remaining arguments as an options object.

Now we need to check if the options object is set before accessing its values and provide proper fallbacks. On the other hand, calling the createUser function now looks very clean.

The first two arguments are pretty obvious, and we can now optionally provide options when needed.

Share This:    Facebook Twitter

Total Pageviews

My Social Profiles

View Sonal's profile on LinkedIn

Tags

__proto__ $Browser Access Grants Accessor properties Admin Ajax AllowsCallouts Apex Apex Map Apex Sharing AssignmentRuleHeader AsyncApexJob Asynchronous Auth Provider AWS Callbacks Connected app constructor Cookie CPU Time CSP Trusted Sites CSS Custom settings CustomLabels Data properties Database.Batchable Database.BatchableContext Database.query Describe Result Destructuring Dynamic Apex Dynamic SOQL Einstein Analytics enqueueJob Enterprise Territory Management Enumeration escapeSingleQuotes featured Flows geolocation getGlobalDescribe getOrgDefaults() getPicklistValues getRecordTypeId() getRecordTypeInfosByName() getURLParameters Google Maps Governor Limits hasOwnProperty() Heap Heap Size IIFE Immediately Invoked Function Expression Interview questions isCustom() Javascript Javascript Array jsForce Lightning Lightning Components Lightning Events lightning-record-edit-form lightning:combobox lightning:icon lightning:input lightning:select LockerService Lookup LWC Manual Sharing Map Modal Module Pattern Named Credentials NodeJS OAuth Object.freeze() Object.keys() Object.preventExtensions() Object.seal() Organization Wide Defaults Override PDF Reader Performance performance.now() Permission Sets Picklist Platform events Popup Postman Primitive Types Profiles Promise propertyIsEnumerable() prototype Query Selectivity Queueable Record types Reference Types Regex Regular Expressions Relationships Rest API Rest Operator Revealing Module Pattern Role Hierarchy Salesforce Salesforce Security Schema.DescribeFieldResult Schema.DescribeSObjectResult Schema.PicklistEntry Schema.SObjectField Schema.SObjectType Security Service Components Shadow DOM Sharing Sharing Rules Singleton Slots SOAP API SOAP Web Services SOQL SOQL injection Spread Operator Star Rating stripInaccessible svg svgIcon Synchronous this Token Triggers uiObjectInfoApi Upload Files VSCode Web Services XHR
Scroll To Top