013_REST Service
1、REST API :it’s an excellent choice of technology for use with mobile applications and web projects.
简介:REST API is a simple and powerful web service based on RESTful principles.
资源类别:It exposes all sorts of Salesforce functionality via REST resources and HTTP methods.
数据操作:For example, you can create, read, update, and delete(CRUD) records, search or query your data, retrieve object metadata, and access information about limits in your org.
支持格式:REST API supports both XML and JSON.
Rest请求四大构成要素:A REST request consists of four components: a resource URI, an HTTP method, request headers, and a request body.
工具:Workbench、check out cURL or Postman
URI(/services/data/v36.0):For convenience, the top-level domain is omitted from the displayed URI. For example, the full URI of the resource that’s prepopulated in the URI text box is https://foo.my.salesforce.com/services/data/v36.0.
注意:
在解析某一对象元数据时,所有小写,如:/services/data/v39.0/sobjects/account/describe
在使用Post HTTP Methond插入数据时注意,字符串必须使用双引号,如下:Phone类型数据也写成双引号
最佳实践:
1、插入记录
背景(/services/data/v39.0/sobjects/account Post Workbench)
{
"Name": "A-Post Test Account",
"Type": "Prospect",
"Phone": "(023) 444-1837"
}
https://componentstest-dev-ed.my.salesforce.com/services/data.json查看版本系列/.xml
2、查找记录
/services/data/v39.0/sobjects/account/0012800001VHuls.xml (xml格式)
/services/data/v39.0/sobjects/contact/00328000015jLeS/account (查询父记录)
背景(Get Workbench)
/services/data/v39.0/query/?q=SELECT+Name+FROM+Account+WHERE+Phone='(023)+444-1837'
Use Apex REST API when you want to expose your Apex classes and methods so that external applications can access your code through REST architecture.
Apex REST API supports both OAuth 2.0 and Session ID for authorization.
Rest Resource:a single data record, a collection of records, or even dynamic real-time information. URI
standard HTTP methods{HEAD, GET, POST, PATCH, DELETE} no PUT, PUT was used to replace the entire resource, not used in Force.com REST API.
CRUD
Method & Function
====================================================
HTTP method CRUD
———————————————
HEAD R(Retrieve information but lacks resp and body)
GET R(Retrieve information)
POST C(create a new object)
PATCH U(update a record)
DELETE D(delete a record)
Exposing REST Service - Endpoint:
===================================
1.For Security End Points: Use a connected App
2.For Open End Points: Use Salesforce Sites
Calling REST Service:
例子参照https://trailhead.salesforce.com/apex_integration_services/apex_integration_webservices
1.在sfdc 创建webservice
@RestResource(urlMapping='/Cases/*') global with sharing class CaseManager { @HttpGet global static Case getCaseById() { RestRequest request = RestContext.request; // grab the caseId from the end of the URL 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); // Match case by Id, if present. // Otherwise, create new case. upsert thisCase; // Return the 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]; // Deserialize the JSON string into name-value pairs Map<String, Object> params = (Map<String, Object>)JSON.deserializeUntyped(request.requestbody.tostring()); // Iterate through each parameter field and value for(String fieldName : params.keySet()) { // Set the field and value on the Case sObject thisCase.put(fieldName, params.get(fieldName)); } update thisCase; return thisCase.Id; } }
2. java部分代码比较传统:
import java.io.IOException; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicHeader; import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.json.JSONTokener; import com.sforce.soap.enterprise.sobject.Case; public class RestCases { static final String USERNAME = "****"; static final String PASSWORD = "****"; static final String LOGINURL = "https://test.salesforce.com"; static final String GRANTSERVICE = "/services/oauth2/token?grant_type=password"; // Setup->Apps->Connected Apps // Consumer Key static final String CLIENTID = "3MVG9Nvmjd9lcjRn1zxB6kEIvpKB3iU8Dbklu4CDQGMoDG.gNreZYwwSHDUBl2cei.sSlHa.ZddSxX2Ccs8Of"; // Consumer Secret static final String CLIENTSECRET = "4755208982540307099"; private static String REST_ENDPOINT = "/services/apexrest"; private static String baseUri; private static Header oauthHeader; private static Header prettyPrintHeader = new BasicHeader("X-PrettyPrint", "1"); /** * 判断是否可以访问sfdc return:可以访问sfdc的rest则返回true,否则返回false * */ private static boolean isAccessable() { HttpClient httpclient = HttpClientBuilder.create().build(); // Assemble the login request URL String loginURL = LOGINURL + GRANTSERVICE + "&client_id=" + CLIENTID + "&client_secret=" + CLIENTSECRET + "&username=" + USERNAME + "&password=" + PASSWORD; // Login requests must be POSTs HttpPost httpPost = new HttpPost(loginURL); HttpResponse response = null; try { // Execute the login POST request response = httpclient.execute(httpPost); } catch (ClientProtocolException cpException) { cpException.printStackTrace(); } catch (IOException ioException) { ioException.printStackTrace(); } // verify response is HTTP OK final int statusCode = response.getStatusLine().getStatusCode(); if (statusCode != HttpStatus.SC_OK) { System.out.println("Error authenticating to Force.com: " + statusCode); return false; } String getResult = null; try { getResult = EntityUtils.toString(response.getEntity()); } catch (IOException ioException) { ioException.printStackTrace(); } JSONObject jsonObject = null; String loginAccessToken = null; String loginInstanceUrl = null; try { jsonObject = (JSONObject) new JSONTokener(getResult).nextValue(); loginAccessToken = jsonObject.getString("access_token"); loginInstanceUrl = jsonObject.getString("instance_url"); } catch (JSONException jsonException) { jsonException.printStackTrace(); } baseUri = loginInstanceUrl + REST_ENDPOINT + "/Cases"; oauthHeader = new BasicHeader("Authorization", "OAuth " + loginAccessToken); System.out.println("oauthHeader1: " + oauthHeader); System.out.println(response.getStatusLine()); System.out.println("Successful login"); System.out.println("instance URL: " + loginInstanceUrl); System.out.println("access token/session ID: " + loginAccessToken); System.out.println("baseUri: " + baseUri); return true; } public static void main(String[] args) { // Case getCases = getCaseById("500O0000005ysCuIAI"); // if (getCases != null) { // System.out.println("Cases Num :" + getCases.getCaseNumber()); // } // System.out.println(":::::::::creat:::::::::::"); // createCase("test", "a", "origin", "priority"); // System.out.println(":::::::::Delete:::::::::"); // deleteCase("500O0000005ysCuIAI"); Case updateCases = new Case(); updateCases.setId("500O0000005ysCuIAI"); updateCases.setSubject(""); updateCases.setStatus("test cases Name"); updateCases.setOrigin("10000"); updateCases.setPriority("10000"); upsertCase(updateCases); } // Update Case using REST HttpPut public static void upsertCase(Case updateCases) { try { if(isAccessable()) { String uri = baseUri + "/upsertCase/"+updateCases.getId(); JSONObject cases = new JSONObject(); cases.put("Subject", updateCases.getSubject()); cases.put("Status", updateCases.getStatus()); cases.put("Origin", updateCases.getOrigin()); cases.put("Priority", updateCases.getPriority()); org.apache.http.client.methods.HttpPatch httpPatch = new org.apache.http.client.methods.HttpPatch(uri); HttpClient httpClient = HttpClientBuilder.create().build(); httpPatch.addHeader(oauthHeader); httpPatch.addHeader(prettyPrintHeader); StringEntity body = new StringEntity(cases.toString(1)); body.setContentType("application/json"); httpPatch.setEntity(body); //Make the request HttpResponse response = httpClient.execute(httpPatch); //Process the response int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { System.out.println("Updated the cases successfully."); } else { System.out.println("cases update NOT successfully. Status code is " + statusCode); } } }catch (JSONException e) { System.out.println("Issue creating JSON or processing results"); e.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } catch (NullPointerException npe) { npe.printStackTrace(); } } // Delete Case using REST HttpDelete public static void deleteCase(String caseId) { try { if(isAccessable()) { String uri = baseUri + "/deleteCase" + "/" + caseId; HttpClient httpClient = HttpClientBuilder.create().build(); HttpDelete httpDelete = new HttpDelete(uri); httpDelete.addHeader(oauthHeader); httpDelete.addHeader(prettyPrintHeader); //Make the request HttpResponse response = httpClient.execute(httpDelete); //Process the response int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { System.out.println("Deleted the cases successfully."); } else { System.out.println("cases delete NOT successful. Status code is " + statusCode); } httpDelete.releaseConnection(); } } catch (IOException ioe) { ioe.printStackTrace(); } catch (NullPointerException npe) { npe.printStackTrace(); } } // Create Cases using REST HttpPost public static void createCase(String subject, String status,String origin, String priority) { try { if(isAccessable()) { String uri = baseUri + "/createCase"; JSONObject cases = new JSONObject(); cases.put("subject", subject); cases.put("status", status); cases.put("origin", origin); cases.put("priority",priority); System.out.println("JSON for cases record to be inserted:\n" + cases.toString(1)); //Construct the objects needed for the request HttpClient httpClient = HttpClientBuilder.create().build(); System.out.println("oauthHeader" + oauthHeader); HttpPost httpPost = new HttpPost(uri); httpPost.addHeader(oauthHeader); httpPost.addHeader(prettyPrintHeader); httpPost.addHeader("encoding", "UTF-8"); // The message we are going to post StringEntity body = new StringEntity(cases.toString(1)); body.setContentType("application/json"); httpPost.setEntity(body); //Make the request HttpResponse response = httpClient.execute(httpPost); System.out.print("response : " + response.toString()); //Process the results int statusCode = response.getStatusLine().getStatusCode(); System.out.println("status code : " + statusCode); if (statusCode == HttpStatus.SC_OK) { String response_string = EntityUtils.toString(response.getEntity()); if(response_string != null ) { System.out.println("New cases id from response: " + response_string); } } else { System.out.println("Insertion unsuccessful. Status code returned is " + statusCode); } httpPost.releaseConnection(); } } catch (JSONException e) { System.out.println("Issue creating JSON or processing results"); e.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } catch (NullPointerException npe) { npe.printStackTrace(); } } // Get Case Using REST HttpGet public static Case getCaseById(String casesId) { try { if (isAccessable()) { String uri = baseUri + "/updateCaseFields/" + casesId; System.out.println(uri); HttpClient httpClient = HttpClientBuilder.create().build(); HttpGet httpGet = new HttpGet(uri); httpGet.addHeader(oauthHeader); httpGet.addHeader(prettyPrintHeader); // Make the request HttpResponse response = httpClient.execute(httpGet); // Process the response int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_OK) { String response_string = EntityUtils.toString(response .getEntity()); System.out.println("response_string : " + response_string); JSONArray jsonArray = new JSONArray("["+response_string+"]"); JSONObject jsonObject = null; if (jsonArray.length() > 0) { jsonObject = jsonArray.getJSONObject(0); } Case cases = new Case(); if (jsonObject != null) { cases.setCaseNumber(jsonObject.getString("CaseNumber")); } return cases; } else { return null; } } } catch (JSONException e) { System.out.println("Issue creating JSON or processing results"); e.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } catch (NullPointerException npe) { npe.printStackTrace(); } return null; } }
贴图是 Workbench 测试接口