Salesforce REST 接口集成服务(二)

Salesforce REST 接口集成服务 一文中,主要讲述了如何调用外部服务器的接口,那么该如何开放Salesforce内部接口给外部系统呢?

将Apex类作为Rest Web服务可用非常简单

  • 定义Class 为Global
  • 定义Method为global static
  • 在类和方法上添加注解,比如@HttpGet

类似这样:

@RestResource(urlMapping=‘/Account/*‘)
global with sharing class MyRestResource {
    @HttpGet
    global static Account getRecord() {
        // 写入代码
        return null;
    }
}

在MyRestResource上,我们使用了@RestResource(urlMapping=‘/Account/*‘) 进行标注,那么访问该Class的URL路径即

https://yourInstance.salesforce.com/service/apexrest/Account/*

Tips: URL区分大小写,并且可以包含通配符(*)

其中https://yourInstance.salesforce.com为Salesforce组织域名,/service/apexrest是固定关键字,/Account/*是每个开放的接口映射的路径

Tips: 如果是托管包中包含Apex REST方法时,需要加上托管包命名空间,比如MyRestResource类在名为packageNamespace的托管程序包命名空间中,那么通过REST调用这些方法使用的URL格式为 https://instance.salesforce.com/services/apexrest/packageNamespace/Account/*

在每一个Salesforce类中,方法上的注解共有五种,且每种仅能出现一次

简单说,@HttpGet 用于读取检索Salesforce系统中的数据,@HttpPost用于创建记录到Salesforce中,@HttpDelete 用于删除Salesforce中的记录,@HttpPut用于更新Salesforce中的记录,特殊的是,如果有的字段没有传值,会将原本记录上的值置空,类似于Upsert,@HttpPatch 同样用于更新Salesforce中的值,不同于HttpPut的一点是,你传什么字段就更新什么字段,不会说覆盖没有传递的字段值

@RestResource(urlMapping=‘/Cases/*‘)
global with sharing class CaseManager {
    @HttpGet
    global static Case getCaseById() {
        RestRequest request = RestContext.request;
        // 从URL末尾获取case Id
        String caseId = request.requestURI.substring(
          request.requestURI.lastIndexOf(‘/‘)+1);
        Case result =  [SELECT CaseNumber,Subject,Status,Origin,Priority
                        FROM Case
                        WHERE Id = :caseId];
        return result;
    }
    @HttpPost
    global static ID createCase(String subject, String status,
        String origin, String priority) {
        Case thisCase = new Case(
            Subject=subject,
            Status=status,
            Origin=origin,
            Priority=priority);
        insert thisCase;
        return thisCase.Id;
    }
    @HttpDelete
    global static void deleteCase() {
        RestRequest request = RestContext.request;
        String caseId = request.requestURI.substring(
            request.requestURI.lastIndexOf(‘/‘)+1);
        Case thisCase = [SELECT Id FROM Case WHERE Id = :caseId];
        delete thisCase;
    }
    @HttpPut
    global static ID upsertCase(String subject, String status,
        String origin, String priority, String id) {
        Case thisCase = new Case(
                Id=id,
                Subject=subject,
                Status=status,
                Origin=origin,
                Priority=priority);
        // ID区分大小写
        upsert thisCase;
        // 返回case Id
        return thisCase.Id;
    }
    @HttpPatch
    global static ID updateCaseFields() {
        RestRequest request = RestContext.request;
        String caseId = request.requestURI.substring(
            request.requestURI.lastIndexOf(‘/‘)+1);
        Case thisCase = [SELECT Id FROM Case WHERE Id = :caseId];
        // 将JSON字符串反序列化
        Map<String, Object> params = (Map<String, Object>)JSON.deserializeUntyped(request.requestbody.tostring());
        // 遍历
        for(String fieldName : params.keySet()) {
            // 赋值
            thisCase.put(fieldName, params.get(fieldName));
        }
        update thisCase;
        return thisCase.Id;
    }
}

Apex REST支持OAuth2.0 和会话身份验证两种机制,不过在进行接口测试时,Salesforce提供了WorkBench来简化测试流程

使用Salesforce账号登录WorkBench,然后选择 utilities | REST Explorer,选择 POST方式,如下图:

点击Execute后,即可查看接口执行结果如下,点击Show Raw Response可以查看接口返回的原始信息

其他的GET等标准方式测试方式同POST.

Tips: Workbench是一套功能强大的基于Web的工具套件,供管理员和开发人员通过Lightning Platform API与组织进行交互。通过Workbench,可以使用会话身份验证,并使用用户名和密码登录到Salesforce,从而使用REST资源管理器调用REST服务

如果考虑对API端点进行版本控制,以便可以在不破坏现有代码的情况下提供功能升级,我们可以创建两个类来指定/ Cases / v1 / *和/ Cases / v2 / *的URL映射,实现接口版本的平滑切换

最后,测试Apex REST类与测试任何其他Apex类相似,只需通过传入参数值来调用类方法,然后验证结果。 对于不带参数或依赖REST请求中信息的方法,可以通过模拟REST请求类覆盖测试

// 模拟一个Rest请求
RestRequest request = new RestRequest();
// 模拟REST请求参数
request.requestUri = ‘https://yourInstance.salesforce.com/services/apexrest/Cases/‘ + recordId;
request.httpMethod = ‘GET‘;
request.params.put(‘status‘, ‘Working‘);
// 最后分配这个REST请求给RestContext
RestContext.request = request;

所以CaseManager的测试类如下

@IsTest
private class CaseManagerTest {
    @isTest static void testGetCaseById() {
        Id recordId = createTestRecord();
        //  模拟Request 请求
        RestRequest request = new RestRequest();
        request.requestUri = ‘https://yourInstance.salesforce.com/services/apexrest/Cases/‘  + recordId;
        request.httpMethod = ‘GET‘;
        RestContext.request = request;
        // 调用测试方法
        Case thisCase = CaseManager.getCaseById();
        //  断言验证结果
        System.assert(thisCase != null);
        System.assertEquals(‘Test record‘, thisCase.Subject);
    }
    @isTest static void testCreateCase() {
        ID thisCaseId = CaseManager.createCase(‘Ferocious chipmunk‘, ‘New‘, ‘Phone‘, ‘Low‘);
        System.assert(thisCaseId != null);
        Case thisCase = [SELECT Id,Subject FROM Case WHERE Id=:thisCaseId];
        System.assert(thisCase != null);
        System.assertEquals(thisCase.Subject, ‘Ferocious chipmunk‘);
    }
    @isTest static void testDeleteCase() {
        Id recordId = createTestRecord();
        // 模拟Request 请求
        RestRequest request = new RestRequest();
        request.requestUri =  ‘https://yourInstance.salesforce.com/services/apexrest/Cases/‘  + recordId;
        request.httpMethod = ‘GET‘;
        RestContext.request = request;
        // 调用测试方法
        CaseManager.deleteCase();
        // 验证结果是否删除
        List<Case> cases = [SELECT Id FROM Case WHERE Id=:recordId];
        System.assert(cases.size() == 0);
    }
    @isTest static void testUpsertCase() {
        ID case1Id = CaseManager.upsertCase( ‘Ferocious chipmunk‘, ‘New‘, ‘Phone‘, ‘Low‘, null);
        System.assert(Case1Id != null);
        Case case1 = [SELECT Id,Subject FROM Case WHERE Id=:case1Id];
        System.assert(case1 != null);
        System.assertEquals(case1.Subject, ‘Ferocious chipmunk‘);
        // 更新状态 New → Working
        ID case2Id = CaseManager.upsertCase(‘Ferocious chipmunk‘, ‘Working‘, ‘Phone‘, ‘Low‘, case1Id);
        // 验证是否更新
        System.assertEquals(case1Id, case2Id);
        Case case2 = [SELECT Id,Status FROM Case WHERE Id=:case2Id];
        System.assert(case2 != null);
        System.assertEquals(case2.Status, ‘Working‘);
    }
    @isTest static void testUpdateCaseFields() {
        Id recordId = createTestRecord();
        RestRequest request = new RestRequest();
        request.requestUri = ‘https://yourInstance.salesforce.com/services/apexrest/Cases/‘ + recordId;
        request.httpMethod = ‘PATCH‘;
        request.addHeader(‘Content-Type‘, ‘application/json‘);
        request.requestBody = Blob.valueOf(‘{"status": "Working"}‘);
        RestContext.request = request;
        ID thisCaseId = CaseManager.updateCaseFields();
        System.assert(thisCaseId != null);
        Case thisCase = [SELECT Id,Status FROM Case WHERE Id=:thisCaseId];
        System.assert(thisCase != null);
        System.assertEquals(thisCase.Status, ‘Working‘);
    }
    // 测试工具类
    static Id createTestRecord() {
        Case caseTest = new Case(
            Subject=‘Test record‘,
            Status=‘New‘,
            Origin=‘Phone‘,
            Priority=‘Medium‘);
        insert caseTest;
        return caseTest.Id;
    }
}

参考数据:

https://trailhead.salesforce.com/content/learn/modules/apex_integration_services/apex_integration_webservices

原文地址:https://www.cnblogs.com/mysalesforce/p/12597674.html

时间: 2025-01-17 05:55:24

Salesforce REST 接口集成服务(二)的相关文章

Salesforce SOAP 接口集成服务

Salesforce 使用Apex调用外部数据的接口有两种方式:SOAP 和 REST SOAP:Web服务使用XML格式的文件调用服务器,通常需要WSDL文档来生成代码 REST:HTTP使用REST格式的文件调用服务器,推荐使用 基于WSDL的CallOut适用于SOAP方式,HTTP方式可以使用任何的HTTP Service,SOAP或者REST都可以,推荐使用REST方式. 在使用SOAP方式调用接口时,可以借助WSDL2Apex工具将XML文件生成Apex类 在Setup上搜索 Ape

JavaSE入门学习21:Java面向对象之接口(interface)(二)

一接口实现的多态 在上一篇博文:JavaSE入门学习20:Java面向对象之接口(interface)(一)中提到了接口的实现存在多态性,那么 这一篇主要就要分析接口实现的多态. 实例一 Test.java源文件代码: public class Test{ public static void main(String[] args){ //实现接口Singer Singer s1 = new Student("Amy"); s1.sing(); s1.sleep(); s1.study

重新开发Jumpserver用户认证模块,调用独立认证接口(二)

一.urls.py # --*--coding:utf-8--*-- from django.conf.urls import patterns, url urlpatterns = patterns('myauth.login', url(r'^login/$', 'do_login', name='login'), url(r'^logout/$', 'do_logout', name='logout'), ) 二.myauth_backend.py Jms_Users 是继承Django的

java微信接口之二—获取用户组

一.微信获取用户组接口简介 1.请求 该请求也是GET方式请求.请求的url格式如下: https://api.weixin.qq.com/cgi-bin/groups/get?access_token=ACCESS_TOKEN 其中ACCESS_TOKEN是之前我们获取到的. 2.响应 该响应也是以json方式返回的 正确的时候返回的数据: { "groups": [ { "id": 0, "name": "未分组", &q

关于微信接口生成二维码跳转至关注页面

<html><head></head><body><form method="post"> </form></body></html><?php function vpost($url,$data){ // 模拟提交数据函数 $curl = curl_init(); // 启动一个CURL会话 curl_setopt($curl, CURLOPT_URL, $url); // 要访问的

python3调用NowAPI接口实现二维码生成工具

本人python学习菜鸟一枚,随着对python的学习,感觉python越来越好玩了,上次用接口查询IP地址后,又看到有道词典查询.二维码生成等接口相关的方法,并对其做了简单的尝试,确实是挺好玩的.所以将整个过程记录下来.分享在此,供大家一起交流学习. 1.基本环境 系统:windows 7 开发环境:pycharm python3 相关的模块和库  urlib  urllib.parse 2.NowAPI简单的介绍 NowAPI是一家 数据服务公司,提供大量的数据接口,对于我们这种学习的菜鸟来

python接口自动化测试二:python代码实现接口测试

url = '接口地址' r = requests.get(url)           #发送get请求 print(r.status_code)            #打印状态码,若有重定向,返回的是重定向之后的代码 print(r.headers)                #打印返回的报头(头部) print(r.text)                   #查看返回结果的文本形式 r.status_code                #响应状态码 r.content   

python接口自动化测试二十三:文件上传

# 以禅道为例: 一.创建一个类,类里面写一个登录方法: import requestsclass LoginZentao(): def __init__(self, s): # 初始化 self.s = s # 定义一个全局的s def login(self): r = self.s.post() # self.s调用全局的s pass if __name__=='__main__': s = requests.session() zentao = LoginZentao(s) # 类实例化为

Java抽象类和接口(二)

***************************接口********************************* 一.why 需求一直不变的时候可以不使用接口, 需求经常发生改变推荐使用接口... 软件产品中需求会经常改变,所以一般都要使用接口... 体现了可维护.可扩展的优点 二.什么是接口 一组规范的集合(包含属性规范.行为规范),用的最多的是行为规范.. USB插槽(实现) != 接口(规范.看不见摸不着的) 网络中的协议也是规范,相当于接口... 三.how 如何定义接口 使