외부 주문시스템에서 배송이 시작되거나 프린터 카트리지를 변경해야 하는 등 외부 시스템의 변동사항을 세일즈포스 org 내에서 알림을 받고 싶은 경우가 있을 수 있다. 그럴 경우!!!!!! Platform Event를 사용하면 시스템을 모니터링하고 변경 사항을 다른 시스템에 전달할 수 있다.
Event-Driven 시스템의 구성요소는 다음과 같다.

Event: 비즈니스 프로세스 상에서 변경된 사항Event message: 이벤트에 대한 데이터가 포함된 메시지. event notification 이라고도 한다.Event producer: 이벤트 메세지를 보내는 주체. 외부 주문시스템 등Evnet consumer: 채널에서 이벤트를 구독하는 주체.Event channel: event producer가 메시지를 보내고 event consumer가 구독하는 곳. 여러 플랫폼 이벤트를 그룹화해서 구독하거나 보낼수도 있다!Event bus: 이벤트 저장장소 및 전달 서비스. 이벤트를 일정시간 저장해주기 때문에, consumer 측에서 놓친 이벤트를 검색할 수 있다. 이벤트 버스는 시간순으로 정렬된 이벤트 로그를 기반으로 한다.
Event-Driven 모델은 특정 상태에 대한 정보를 얻기 위해 서버에 요청할 필요가 없다. 이벤트 채널을 구독하고 새로운 상태가 발생할 때마다 이벤트 버스로 전달된 이벤트를 전달받기만 하면 되니까! producer-consumer 관계에도 종속성 없이 거의 실시간으로 반응이 가능하다. 완죠니 프로세스가 단순해짐!
플랫폼 이벤트를 사용하는 예시는 여기서 참고
플랫폼 이벤트는 Custom Object 처럼 custom 할 수 있다. 필드도 추가할 수 있고, 이름도 지정해줄 수 있다. 그렇다면.. Event Message는 무엇일까?
Event message는 record가 Object의 인스턴스인 것처럼, 플랫폼 이벤트의 인스턴스이다. 다만 레코드와 달리 update하거나 delete 할 수 없으며, user가 사용하는 interface(org)내에서 볼 수 없다.
플랫폼 이벤트에 대한 read 및 create 권한은 profile과 permission set에서 설정할 수 있다. 만드는 방법은 Setup에서 Platform Event를 검색해서 org 상에서 만들면 된다!!
상단 이미지를 보면 Publish Behavior를 선택하는 항목이 있다. 하나씩 알아보자!!
Publish After Commit: 이 경우엔 이벤트가 발생하고, subscriber가 트랜잭션이 commit하는 데이터에 의존하는 경우에 사용한다.Publish After Commit으로 설정하여야 한다.Publish immediately: 이 경우엔 트랜잭션 성공 여부에 관계 없이 호출을 하자마자 publish를 한다. 서로 의존성이 없는 프로세스에 사용한다. 이 옵션을 사용하면 트랜잭션에서 데이터가 커밋되기 전에 subscriber가 이벤트 메세지를 받을 수 있다.Governor limit
Publish After Commit으로 구성된 이벤트의 경우 각 DML문 하나로 계산된다. 이에 반해,Publish immediately로 구성된 이벤트의 경우 EventBus.Publish() 150개로 제한되어 계산된다. 한도 사용량을 확인하고 싶을 경우엔Limits.getPublishImmediateDML()를 사용하여 확인할 수 있다.
Custom Object의 API Name 맨 뒤에는 __c가 붙는 것처럼, Platform Event의 API Name 맨 뒤에도 __e가 붙는다. Apex나 Pub/Sub API로 이벤트를 참조할 때마다 API Name을 올바르게 사용해야한다.
Cloud_News__e newsEvent = new Cloud_News__e(
Location__c='Mountain City',
Urgent__c=true,
News_Content__c='Lake Road is closed due to mudslides.');
Database.SaveResult sr = EventBus.publish(newsEvent);
if (sr.isSuccess()) {
System.debug('Successfully published event.');
} else {
for(Database.Error err : sr.getErrors()) {
System.debug('Error returned: ' +
err.getStatusCode() +
' - ' +
err.getMessage());
}
}
이벤트 메시지를 게시하려면 이벤트 인스턴스를 생성하고 이를 EventBus.publish() 메소드에 전달하면 된다. 상단 코드를 보자.
Cloud_News__e라는 이벤트의 인스턴스를 생성해서 newsEvent라는 변수에 저장한다.EventBus.publish() 메소드에 이벤트 인스턴스를 전달한다.Database.SaveResult 객체에 게시 결과를 포함하여 반환하기 때문에, sr이라는 변수를 선언하여 저장한다.sr의 isSuccess() 메소드가 true를 반환한다면, Salesforce의 큐에 추가되고 이벤트 메시지가 비동기로 publish 된다.sr의 isSuccess() 메소드가 false를 반환한다면, DB에러가 발생하여 sr에 반환된다. 반환된 에러는 getErrors() 메소드로 DB에러를 return 받을 수 있다.꼭 코드를 작성하지 않더라도 flow나 process builder로 받을 수 있다.
플랫폼 이벤트를 publish 했으니 이에 대한 알림을 받으려면 subscribe해야겠지? Apex, trigger, flow, process 등을 활용해서 세일즈포스 내에서 알림을 받을 수 있도록 할 수도 있고, 외부 App에서는 Pub/Sub API를 활용해서 이벤트를 subscribe 할 수 있다.
플랫폼 이벤트는 after insert trigger에만 지원된다. trigger는 따로 구문을 넣을 필요 없이 자동으로 이벤트를 subscribe한다. 코드로 확인해보자.
trigger CloudNewsTrigger on Cloud_News__e (after insert) {
List<Case> cases = new List<Case>();
Group queue = [SELECT Id FROM Group WHERE Name='Regional Dispatch' AND Type='Queue'];
for (Cloud_News__e event : Trigger.New) {
if (event.Urgent__c == true) {
Case cs = new Case();
cs.Priority = 'High';
cs.Subject = 'News team dispatch to ' +
event.Location__c;
cs.OwnerId = queue.Id;
cases.add(cs);
}
}
insert cases;
}
플랫폼 이벤트 trigger는 디버그 logging을 할 수 없다. 따라서 Setup에서 debug log를 입력하여 생성한 뒤 추적해야 한다.
이벤트 처리 순서
트리거는 platform event가 수신된 순서대로 처리한다. 이벤트 순서는 replayID를 기준으로 한다.
비동기 트리거 실행
platform event 트리거는 자체 프로세스에서 비동기식으로 실행된다. 중요한 점은, 이벤트를 publish한 트랜잭션과는 상관이 없기 때문에, 이벤트가 publish되는 시점과 이벤트를 처리하는 시점 사이에 지연이 발생할 수 있다. 그니까! 이벤트 publish 후에 즉시 trigger 실행 결과를 사용하는 로직은 위험할 수 있음!!!
사용자 명시
플랫폼 이벤트 트리거는 process 자체에서 실행되기 때문에 running user와는 관계가 없다. 따라서 trigger를 통해 레코드를 생성하는 경우 user를 명시해줄 수 있다. 근데 이 경우도 running user 아래에서 실행되도록 정의할 수도 있음 여기 참고
Apex gorvernor limit
이벤트 트리거에는 Apex limit이 적용된다.
트리거 batch 크기
batch 크기는 최대 2000개의 이벤트 메세지까지 수용할 수 있다. 원래 object trigger batch size는 200개. batch의 size는 Trigger.New의 list 크기를 의미한다.
import { subscribe, unsubscribe, onError, setDebugFlag, isEmpEnabled }
from 'lightning/empApi';
import한 메소드들을 JS 코드에서 호출해서 사용하면 된다. 더 자세한 내용은 요기
가 가능하다는데.. 아직까진 먼말인지 모르겠다.. 어려버ㅠ!!!!!!
갈 길이 멀다.. 실제로 사용해보지 않는 이상 이해하기 어려운 부분이 너무 많다ㅠ;