salesforce零基础学习(一百零三)项目中的零碎知识点小总结(五)
本篇参考:Salesforce Admin篇(四) Security 之Two-Factor Authentication & Single Sign On
一. Salesforce acting as IdP, IdP initiated
我们在前一个博客中也解释了 SSO中的 SP(Service Provider) 以及 IdP(Identity Provider),这里举一个简单的例子进行深化概念。 help.salesforce.com 通过salesforce的账号进行登录, salesforce端进行相关的账号信息认证,然后认证通过以后重新跳转到 help.salesforce.com,然后根据你的sf账号的权限可以访问相关的help中的文档以及操作。在这个demo中,help网址就是一个SP,用于提供服务,salesforce就是IdP,作为身份认证用。
我们在项目中通常使用 SF和其他的平台做SSO,主要有三种的形式。
- Salesforce 作为 SP,其他系统作为IDP;
- Salesforce作为IdP,并且访问SP的内容是由 IdP初始化;
- Salesforce作为IdP,并且访问内容由SP初始化。
说起来有点绕,通过上面的参考的 SSO进行一个例子。我们之前的SSO实现的是salesforce to salesforce的功能。两个salesforce的环境,其中:
- zero-zhang-dev-ed.my.salesforce.com:作为IdP;
- https://zhangyueqi-3-dev-ed.my.salesforce.com:作为SP;
现在的需求是从IdP的环境有一个URL,点击这个URL可以直接跳转到SP环境的 Account 列表,这个时候,我们需要用到 RelayState参数。
首先我们需要知道如何可以不输入账号密码就可以直接跳转到SP 环境,通过 connected app,我们可以看到SAML Login Information区域有一个 IdP-Initiated Login URL,访问此链接就可以直接跳转到SP。
所以我们需要做的就是在这个URL基础上,添加 RelayState参数,跳转到对端系统的指定位置即可。Account 列表是 /001,所以我们设置 RelayState为/001即实现IdP Initiated的场景。
这里需要注意一点, RelayState区分大小写,只能按照当前的大小写填写,如果大小写有误,则会跳转无效。
二. 标准 Rest API操作数据
我们和外部系统操作时,如果对端只是需要在我们这边去简单的操作数据,没有复杂的逻辑,数据量也还好的情况下,我们完全可以使用标准的 Rest API去操作数据。这种好处是省去了我们写restful接口以及两边系统沟通的时间,只需要了解标准的restful接口规则即可。
我们可以使用CURL方式去访问去操作数据,我们通常操作类型是数据的CRUD,以及通过外键进行C/U。接下来通过workbench进行简单的模拟。
1. 查询场景
1)通过Record Id去查询:使用的Http方式为get,并且访问的格式为 /services/data/v51.0(这里填写版本号)/sobjects/Account(这里填写表的API名称)/Record Id。整体的cURL访问:curl https://yourInstance.salesforce.com/ + 上述的格式即可。
如果我们只想查询这条数据的指定的字段,我们只需要在后面添加参数 ?fields=字段名1,字段名2。 字段之间使用逗号分隔。
2) 通过外键操作数据:我们知道的是,当一个字段设置成外键,他通常都是设置成external id & unique,所以通常通过 external id可以找到唯一的一条数据,在标准的rest api中,我们可以通过external id去获取数据。和上面的写法前面是一样的,后者变化如下 /sObjectName/ 外键字段的API名称/ 外键字段的值。在我们下方的demo中,我们在 Account表中创建了一个外键,API名称为 External_Id__c, 所以下面的链接是 External_Id__c为 Ext_00001的对应的Account数据
3) 通过SOQL语句进行查询:标准 rest接口同样支持使用SOQL去返回指定的list信息。格式为:services/data/v51.0/query/?q=SOQL query, 其中 SOQL使用 + 分隔 。下面demo中在Account表中查询了 Id以及Name。response中包含了记录数以及细节信息,可以通过层级结构进行数据的获取。
2. 新建场景
1) 单表常规操作新建:针对表的创建,因为我们需要request body指定哪些字段创建成哪些值,所以我们的method肯定不可能是 GET了,针对标准的单表创建,类型选择Post,将报文内容放在{}(花括号)中间,然后使用键值对方式,左面是字段的API Name,右面对应相关的值,按照以下的方式即可。点击Execute,我们可以看到 response的结构体返回了新建的Id,结果状态等信息。
2) 级联表(nested records)创建数据:我们很多时候会有针对父子表的操作,标准的rest api同样支持级联表(lookup / master-detail)的创建,当然也只是支持创建操作,如果想要对级联表进行更新或者删除,需要使用相关的record id或者外键去进行操作,此种操作只是支持新建。同样先说一下request method,使用的是post。然后再说一下request URL为:/services/data/v51.0/composite/tree/Account/。这里我们可以看到和上面的区别很大,使用的是 composite/tree,然后后面跟着的是级联表父表的API Name。最后再说明一下request body,我们以下面的例子去进行具体的说明。下面的demo是创建两条 Account数据,第一条Account数据要级联创建 Contact数据自动关联这条 Account,第二条 Account的数据要级联创建Contact以及Case。这里有两个关键点需要说明:
- 每个层级结构中都有一个 referenceId:这个是必须要有的,并且是唯一的,当成功以后referenceId用来对应着成功插入数据的record id,这个可以随便赋值,只要保证唯一即可。
- 我们看到针对子表插入的时候,使用的是 Contacts / Cases等。这个是子表和父表关联时的 Child Relationship Name,因为这两个都是标准表,所以没有__r,如果是自定义表的关系,这个 Child Relationship Name后面需要添加 __r用来代表子表名称。
request body 内容如下所示:
{
"records" :[
{
"attributes" : {"type" : "Account", "referenceId" : "ref1"},
"name" : "SampleAccount1",
"industry" : "Banking",
"Contacts" : {
"records" : [
{
"attributes" : {"type" : "Contact", "referenceId" : "ref2"},
"lastname" : "Smith",
"Title" : "President",
"email" : "sample@salesforce.com"
},{
"attributes" : {"type" : "Contact", "referenceId" : "ref3"},
"lastname" : "Evans",
"title" : "Vice President",
"email" : "sample@salesforce.com"
}
]
}
},
{
"attributes" : {"type" : "Account", "referenceId" : "ref4"},
"name" : "SampleAccount2",
"industry" : "Banking",
"Cases" : {
"records" : [
{
"attributes" : {"type" : "Case", "referenceId" : "ref5"},
"Status": "New",
"Priority": "Meduim",
"Origin" : "Phone"
}
]
},
"Contacts" : {
"records" : [
{
"attributes" : {"type" : "Contact", "referenceId" : "ref6"},
"lastname" : "Jones",
"title" : "President",
"email" : "sample@salesforce.com"
}
]
}
}
]
}
当我们使用这个 request执行以后对应的 response的层级结构如下,我们可以根据层级结构以及 referenceId查看到指定的 recordId,然后可以通过 get方法获取这条记录的详情信息。
3. 更新 / Upsert 场景
1)通过记录ID进行更新:根据前面的内容我们会发现 rest api需要确定的三个核心点: request method / curl / request body。针对记录ID进行更新时, request method选择 patch,curl和通过ID方式获取数据的相同,为 /services/data/v20.0/sobjects/Account/recordId, request body和创建单条数据的方式相同,为键值对方式。demo如下:
需要注意的是,我们看 response内容觉得很怪,因为 update不返回相关的内容,我们可以通过status code来判断,比如我们可以通过204去确定一下是否成功。status code状态相关定义可以查看此链接:https://developer.salesforce.com/docs/atlas.en-us.224.0.api_rest.meta/api_rest/errorcodes.htm
下面的demo来了一个报错的情况,所以我们做update的场景也需要进行相关的异常捕获。
2)通过外键进行 upsert操作:和上面的三步走相同,upsert的request method为 patch,curl 和上面提到的通过外键获取数据相同,然后request body和上面的更新数据的报文相同。这里直接来一个例子:
通过下图我们可以看到报文和上面的外键获取数据相同,不做解释,主要看一下 response body。success返回此次操作是否成功,成功情况下为 true,失败的话为false,并且errors存储错误信息,created用来判断当前操作是 insert还是 update,当前的demo为update,所以这项的返回值为false。
4. 删除场景:当我们使用API去进行删除时,request method选择delete,url和通过record id获取数据的url相同,没有request body以及没有response的body。我们可以通过status code来追踪当前的删除是否成功。通过下图我们可以看到,删除成功,没有 response body,status code为204.
总结:本篇小结主要是两点,一个是针对SSO的细节运用,一个是针对标准的 rest api相关的简单接口操作。针对第二点讲的也比较浅显,如果真正第三方使用还需要配置 Oauth2.0等,详情可以查看API文档。这里做一个有意思的引申,我们知道我们做 lightning项目的时候,以lwc为例。操作数据可以通过 LDS(lightning-record-form等)、 wire adapter(getRecord/ updateRecord等)以及后台apex去做复杂的逻辑操作。通过上面的demo,我们是不是也可以考虑使用标准的 rest api去进行数据的操作?当然,Rest API不只是操作数据,还可以对schema进行相关获取,很强大,建议可以快速扫一下。篇中有错误地方欢迎指出,有问题欢迎留言。