Salesforce to other system || other system to salesforce
Connected App是一个允许外部的应用通过API 以及 标准协议来实现和Salesforce交互的架构.
Remote Site salesforce通过REST方式访问外界站点需要添加站点的url
Streaming API/Pub/Sub API Bulk ApI Rest Soap
Rest : REST方式获取外部Service数据以及其他Service访问Salesforce数据操作
Salesforce call other system
将Web Service的授权端点地址添加到Remote Site中
Some Common HTTP Methods
Get and Post
Get 方式传递值直接拼在url 中, post 传递一个json 格式数据
String params = '?subject=test&status=active';
String url == WEB_URL+'/xxx/Sync/SyncTest?'+params;
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint(url);
req.setMethod('GET');
HttpResponse res = h.send(req);
Http http = new Http();
HttpRequest request = new HttpRequest();
request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
request.setMethod('POST');
request.setHeader('Content-Type', 'application/json;charset=UTF-8');
// Set the body as a JSON object
request.setBody('{"name":"mighty moose"}');
HttpResponse response = http.send(request);
// Parse the JSON response
if(response.getStatusCode() != 201) {
System.debug('The status code returned was not expected: ' + response.getStatusCode() + ' ' + response.getStatus());
} else {
System.debug(response.getBody());
}
other system call salesforce
创建Connected App,根据生成的Consumer Key以及Consumer Secret 配置外部系统
@RestResource:曝光此类作为REST资源;
@HttpGet:曝光方法作为REST资源,当有Http get请求发送时,此注解对应的方法会被执行;
@HttpPost:Http post 请求发送时,此注解对应的方法会被执行;
@HttpDelete:当有Http delete请求发送时,此注解对应的方法会被执行;
@HttpPut:当有Http put请求发送时,此注解对应的方法会被执行;
@HttpPatch:当有Http patch请求发送时,此注解对应的方法会被执行。
@HttpGet和@HttpDelete不能有形参,可以通过URL?param或者URL/param方式传过来参数 类和方法需要global,方法需要静态 类需要通过RestResource(UrlMapping='/page/*')注解声明
@RestResource(UrlMapping='/AccountLogic/*')
8 global class AccountRESTController {
10 @HttpGet
11 global static List<Account> getAccountsByIdOrList() {
12 RestRequest request = RestContext.request;
16 String accountId= request.params.get('accountId');
17 String fetchSql;
18 if(accountId!= null) {
19 fetchSql = 'SELECT CreatedById, CreatedDate, IsDeleted, Name,' +
22 ' xxxx FROM Account' +
23 ' where Id = :accountId';
24 } else {
25
29 }
30 List<Account> accountList = Database.query(fetchSql);
31 return accountList ;
32 }
33
34
35 @HttpPost
36 global static Id insertAccount(String accountName,String xxxxx) {
37 return xxx;
49 }
50
51 @HttpDelete
52 global static void deleteGoods() {
53
60 }
61
62 @HttpPut
63 global static ID upsertAccounts(String id,String accountName) {
64
77 }
78
79 @HttpPatch
80 global static ID updateAccounts() {
81
93 }
94
95
96
97 }
自己写的方法可以在workbench中查看测试
/services/apexrest/AccountLogic/getAccountsByIdOrList?accountid=xxxxx
REST API支持JSON和XML两种传输方式,默认为JSON,可通过【HTTP ACCEPT】header来设定
Callout方法在执行后续代码的时候,会等待外部服务器的响应结果,所以Callout方法同样可以在@future(callout=true) 中进行调用,这样Callout方法可以在单独的进程中调用,不会阻塞其他进程,尤其在触发器中调用Callout方法时,必须将其包含在含有@future(callout=true) 的方法中进行
Make Long-Running Callouts with Continuations
<apex:page controller="ContinuationController" showChat="false" showHeader="false">
<apex:form >
<!-- Invokes the action method when the user clicks this button. -->
<apex:commandButton action="{!startRequest}"
value="Start Request" reRender="result"/>
</apex:form>
<!-- This output text component displays the callout response body. -->
<apex:outputText id="result" value="{!result}" />
</apex:page>
public with sharing class ContinuationController {
// Unique label corresponding to the continuation
public String requestLabel;
// Result of callout
public String result {get;set;}
// Callout endpoint as a named credential URL
// or, as shown here, as the long-running service URL
private static final String LONG_RUNNING_SERVICE_URL =
'<Insert your service URL>';
// Action method
public Object startRequest() {
// Create continuation with a timeout
Continuation con = new Continuation(40);
// Set callback method
con.continuationMethod='processResponse';
// Create callout request
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setEndpoint(LONG_RUNNING_SERVICE_URL);
// Add callout request to continuation
this.requestLabel = con.addHttpRequest(req);
// Return the continuation
return con;
}
// Callback method
public Object processResponse() {
// Get the response by using the unique label
HttpResponse response = Continuation.getResponse(this.requestLabel);
// Set the result variable that is displayed on the Visualforce page
this.result = response.getBody();
// Return null to re-render the original Visualforce page
return null;
}
}
code
1.以“2”开头,表示成功:
(1)200:表示“成功”。通常用于GET、HEAD和一些PATCH中。
(2)201:表示“已创建”。通常用于POST和一些PATCH中。
(3)204:表示“没有内容”。通常用于DELETE和一些PATCH中。
2.以“3”开头,表示重定向:
(1)300:当外部ID存在于多条数据中时返回该状态码。即Response Body中包含多条符合的数据。
(2)304:用户在发送请求的header中指定日期时间,如果从这个日期时间开始请求的文件内容未变化,则返回该状态码。(用于指定日期时间的header是【If-Modified-Since】)
3.以“4”开头,表示客户端错误:
(1)400:请求无法被解析,通常是因为JSON或XML body中有错误。
(2)401:Session ID或OAuth令牌无效或过期,在response body中会有相关信息和错误状态码
(3)403:请求被拒绝。查看发送请求的用户是否有权限。若错误信息是“REQUEST_LIMIT_EXCEEDED”,则是超出了组织API请求上限。
(4)404:找不到请求中的信息。检查URI是否正确。
(5)405:请求行中的方法不被允许访问URI
(6)409:请求无法完成,因为当前请求的相关设定中存在冲突。检查请求的API版本是否合适。
(7)410:通知用户该资源已经不可再用,主要是帮助网站管理员维护网站。
(8)412:表示“未满足前提条件”,如用户发送的请求的header中的指定条件无法对应。
(9)414:URI长度过长(超出16384 byte)
(10)415:服务器无法处理请求附带的媒体格式。检查header中的Content Type是否正确。
(11)431:URI和header加在一起的长度超过16384 byte,可能是由于token过长。
4.以“5”开头,表示服务器错误:
(1)500:Lightning Platform发生错误,请求无法处理。请联系Salesforce服务台。
(2)503:服务器无法处理请求。一般是因为系统维护或超载。
SOAP :
根据系统生成的WSDL 文件 ,外部系统通过这个文件进行接口的调用
系统根据外部系统的WSDL文件生成对应的apex class ,调用外部系统
Bulk ApI : 大量的数据处理,batch 处理, 通过excel 等
--BOUNDARY
Content-Type: application/json
Content-Disposition: form-data; name="job"
{
"object":"Contact",
"contentType":"CSV",
"operation": "insert",
"lineEnding" : "LF"
}
--BOUNDARY
Content-Type: text/csv
Content-Disposition: form-data; name="content"; filename="content"
FirstName,LastName,MailingCity
Astro,Nomical,San Francisco
Hootie,McOwl,San Francisco
Appy,Camper,San Francisco
Earnie,Badger,San Francisco
--BOUNDARY--
Streaming API/Pub/Sub API :
如果想使用Streaming API,需要enable api的权限以及streaming api的权限
想要接受通知(notifications),当前登录的user必须针对StreamingChannel表拥有read权限
想要创建和管理通知,当前登录的user必须对StreamingChannel拥有Create权限
Push Topic
ApiVersion:用于指定查询的SQL的版本,37以后系统可以存储24小时以内的事件,必填字段;
Description:PushTopic的描述信息,限定在400个字符以内;
ID:指定一条记录的全局唯一的标识;
isActive:是否可用,关系到PushTopic的限制计数(系统对PushTopic有limitation size);
IsDeleted:指定此PushTopic是否移动到回收站;
Name:PushTopic的名字,定义了渠道的名字,并且此名称必须是唯一的,后期订阅者订阅时,使用的就是这个名字;
NotifyForFields:指定哪些字段被评估生成通知;
NotifyForOperations:指定数据哪种事件操作会生成通知,在api version 29以后,此字段为只读字段;
NotifyForOperationCreate:Create操作是否会生成通知,api29以后可用;
NotifyForOperationDelete:Delete操作是否会生成通知,api29以后可用;
NotifyForOperationUndelete:UnDelete操作是否会生成通知,api29以后可用;
NotifyForOperationUpdate:Update操作是否会生成通知,api29以后可用;
Query:SOQL语句决定了哪些数据符合触发的事件后会发送到渠道。
PushTopic pushTopic = new PushTopic();
pushTopic.Name = 'InvoiceStatementUpdates';
pushTopic.Query = 'SELECT Id, Name, Status__c, Description__c FROM Invoice_Statement__c';
pushTopic.ApiVersion = 61.0;
pushTopic.NotifyForOperationCreate = true;
pushTopic.NotifyForOperationUpdate = true;
pushTopic.NotifyForOperationUndelete = true;
pushTopic.NotifyForOperationDelete = true;
pushTopic.NotifyForFields = 'Referenced';
insert pushTopic;
创建之后可以在workbench查看 Jump To选择Streaming Push Topics
Push Topics 选择刚刚创建的InvoiceStatementUpdates,点击Subscribe,则目前已经模拟订阅了此PushTopic
在系统中修改publish topic 关联的并且符合soql 的数据,则会在Streaming Push Topic 显示具体的修改信息推送消息了
Streaming Channels:
Description : Streaming Channel的描述
ID : Streaming Channel的ID
IsDeleted : 指定Streaming Channel是否被移动到回收站
IsDynamic : 如果为true则在订阅时动态创建channel
LastReferencedDate : 存储当前用户最近一次查看的这条记录的时间戳
Name:绑定的PushTopic,以/u/开始,命名为/u/pushtopic Name
OwnerId : Streaming Channel的owner
外部系统请求订阅,订阅后符合PushTopic 中soql 的数据触发后会发送
内部系统自己也可以调用Streaming Channels
Platform Event:
可以监听系统数据并且满足某种条件下,和自己或者其他外部系统进行交流通讯
创建Platform Event以后,可以选择Publish Behavior,salesforce提供了两个值可供选择: Publish After Commit / Publish Immediately
Publish Immediately如果设置了此种模式, setSavePoint以及rollback不支持,即发送了就发送了,没有某种case回滚模式;反之Publish After Commit可以有回滚操作
Publish Immediately当对一个platform event列表进行publish时,即使有一些失败,成功的那些也会继续进行发布,即保存时allOrNone属性会被自动忽略;
trigger AccountTrigger on Account(after update) {
List<Account__e> needPublishAccountList = new List<Account__e>();
for(Account accountItem : (List<Account>)Trigger.new) {
//some logic
if() {
//new created plat event
Account__e accountPublishItem = new Account__e();
//put account value to event record field
accountPublishItem.Account_Id__c = accountItem.Id;
needPublishAccountList.add(accountPublishItem);
}
}
// publish the event
List<Database.SaveResult> results = EventBus.publish(needPublishAccountList);
}
添加监听, 可以在对应的event 创建trigger 或者其他方式,trigger只能after insert
Change Data Capture:
setup-> change data capture 然后选择需要追踪的表
trigger OpportunityChangeTrigger on OpportunityChangeEvent (after insert) {
for (OpportunityChangeEvent event : Trigger.New) {
// Get some event header fields
EventBus.ChangeEventHeader header = event.ChangeEventHeader;
if (header.changetype == 'UPDATE') {
for (String field : header.changedFields) {
System.debug('Changed field value: ' + field + '. New Value: '
+ event.get(field));
}
}
}
debug log中查看到CDC相关的订阅信息,需要将 Traced Entity Type设置成 Automated Process
自己记录使用