Java developers are quickly moving to Scala, because it’s easier and faster to write, but compiles into Java-compatible byte code. Scala is like Python, but as fast as Java, and allows you to use existing Java libraries. To use Scala with Salesforce, you use the REST API, which allows you to access any object within Salesforce and access its data.
In this blog post you will learn how to use Scala language to make REST APIs calls to Salesforce. The samples are designed to quickly ramp up your team, and are structured to be generic enough that they can be used with any standard object in Salesforce.
The instructions below guide you through the steps of creating the project from scratch, but if you want to cheat you can clone the repository on Github: force-rest-scala.
To build and run Scala with SBT, you need a formal directory structure, which takes the following format.
src
| `-- main
| |-- resources
| | |-- application.conf
| `-- scala
| |
build.sbt
src.
buid.sbt
. Add following content to this file.
name := "ForceSamples"
version := "1.0"
scalaVersion := "2.10.4"
libraryDependencies += "org.apache.httpcomponents" % "httpclient" % "4.5.1"
libraryDependencies += "org.skife.com.typesafe.config" % "typesafe-config" % "0.3.0"
libraryDependencies += "com.google.code.gson" % "gson" % "1.7.1"
Create directories src/main/resources
and src/main/scala under
src
folder.
Create the file src/main/resources/application.conf
file from util/src/main/resources/application.conf.sample
and fill in the values appropriately from your Salesforce organization (for testing purposes like this, you should always use Developer Edition first).
$ cp util $ cp src/main/resources/application.conf.sample \ src/main/resources/application.conf $ cat src/main/resources/application.conf
Update the ""
with appropriate values for ClientId
, ClientSecret
, UserName
, PassWord
,LoginURL
and GrantService
.
force {
UserName = ""
PassWord = ""
LoginURL = ""
GrantService = ""
ClientID = ""
ClientSecret = ""
}
The src/main/scala/Util.scala
file provides common methods for getting access tokens from the REST Endpoints.
Access token GET is implemented in the getAccessToken() method of Util.scala
. We define a class Util
in this file and add a method getAccesssToken()
.
class Util {
def getAccessToken() : String = {
}
}
Getting an access token consists of following steps:
application.conf
into the appropriate variables and create a loginURL:
val UserName = conf.getString("force.UserName")
val PassWord = conf.getString("force.PassWord")
val LoginURL = conf.getString("force.LoginURL")
val GrantService = conf.getString("force.GrantService")
val ClientID = conf.getString("force.ClientID")
val ClientSecret = conf.getString("force.ClientSecret")
val loginURL = LoginURL +
GrantService +
"&client_id=" + ClientID +
"&client_secret=" + ClientSecret +
"&username=" + UserName +
"&password=" + PassWord
client, HttpPost
object post
and call execute(post)
on this client:
val client = new DefaultHttpClient
val post = new HttpPost(loginURL)
val handler = new BasicResponseHandler();
val response = client.execute(post)
println("response:" + response)
val body = handler.handleResponse(response);
gson
library. We also define a custom class Token
into which the access_token is parsed: case class Token(access_token: String, instance_url: String,
id: String,
token_type: String,
issued_at: String,
signature: String)
val gson = new Gson
val jsonObject = gson.fromJson(body, classOf[Token])
access_token = jsonObject.access_token
println("access_token: " + access_token)
Reference Source Code can be found at http://clouddatafacts.com/force.com/code-force-rest-scala/code-getAccessToken.html
Create a generic SObject
class which can be used to encapsulate CRUD operations for the SObject. This is created under the path src/main/scala
src
| `-- main
| |-- resources
| `-- scala
| |-- SObject.scala
class SObject(sObjectN : String) {
var sObjectName: String = sObjectN
}
The URL used to make request depends on the instance where your account was created ( na1, na2, ap1, ap2 etc.) as well the version of the API being used. For this example, we’re using the base URL https://ap2.salesforce.com/services/data/v35.0/sobjects/
.
The function getList()
will be added to the SObject class created above. An HTTPs GET request is made to the URL listed above appended by the object_name.
The header of the HTTP request has Access token set in the HTTP request header.
The complete code listing looks like this:
Content-type
is set to application/json
.
def getList() : String = {
val host = "https://ap2.salesforce.com"
val baseUrl = "/services/data/v35.0/sobjects/"
val util = new Util()
val access_token = util.getAccessToken()
println(access_token)
val url = host + baseUrl + sObjectName
val request = new HttpGet(url)
request.addHeader("Authorization", "Bearer " + access_token)
request.addHeader("Content-type", "application/json")
val client = new DefaultHttpClient
val response = client.execute(request)
val handler = new BasicResponseHandler()
val body = handler.handleResponse(response)
return body
}
This method is called from objects Account
get_list
function to get a list of Accounts.
class SObject
with Object name as Account
. Call the getList() method on the object to get List of Accounts.
object AccountList{ def main(args: Array[String]): Unit = { val sObject = new SObject("Account") val body = sObject.getList() println(body) } }
$ sbt compile
$ sbt run [1] AccountList
Create a new method createSObject()
in the SObject
class. We will do following actions in this method:
url
for Http Post, create a HttpPost
objectThe code listing for the steps defined above can be seen below:
def createSObject(jsonData : String) = { val host = "https://ap2.salesforce.com" val baseUrl = "/services/data/v35.0/sobjects/" val util = new Util() val access_token = util.getAccessToken() println(access_token) val url = host + baseUrl + sObjectName val post = new HttpPost(url) // set the Content-type post.addHeader("Authorization", "Bearer " + access_token) post.setHeader("Content-type", "application/json") // add the JSON as a StringEntity post.setEntity(new StringEntity(jsonData)) // send the post request val response = (new DefaultHttpClient).execute(post) println(response) }
Compile and Run the Program
$ sbt compile $ sbt run
In this section we look at how to use Scala to make a Delete call.
Add a Delete Method deleteSObject
to SObject
class.
accessToken
from Util classUpdate Accounturl
object using objectId
to be deleted and sObjectName
HttpDelete
object from the url
DefaultHttpClient
instanceCode Listing for Delete Account can be found below
def deleteSObject(objectId: String) { val host = "https://ap2.salesforce.com" val baseUrl = "/services/data/v35.0/sobjects/" val util = new Util() val accessToken = util.getAccessToken() println(accessToken) val url = host + baseUrl + sObjectName + "/" + objectId val delete = new HttpDelete(url); delete.addHeader("Authorization", "Bearer " + accessToken) delete.setHeader("Content-type", "application/json") val response = (new DefaultHttpClient).execute(delete) println(response) }
Create a DeleteAccount
Scala object in DeleteAccount.scala
file.
def main(args: Array[String]): Unit
method and create an SObject
instance.objectId
of the Account to be deleted. Please change this to the appropriate value for your environment.sObject.deleteSObject(objectId)
Code listing below shows how the actual SObject is instantiates and deleteSObject method is called on it.
object DeleteAccount{ def main(args: Array[String]): Unit = { val sObject = new SObject("Account") val objectId = "0012800000DR2Ko" sObject.deleteSObject(objectId) } }
Compile and Run the Program
$ sbt compile
$ sbt run
To run a SOQL Query to get data from a SObject follow the steps listed below:
Create a new method executeSOQL(..)
in SObject class
Get accessToken
Create url
Create HttpGet request object
Add Http headers Authorization and Content-Type
Create a new DefaultHttpClient
Execute the Get method, handle the response and display JSON
Complete Code for executeSOQL() method
def executeSOQL(soql: String): String = { val host = "https://ap2.salesforce.com" val baseUrl = "/services/data/v35.0/query/?q=" val util = new Util() val accessToken = util.getAccessToken() println("accessToken: " + accessToken) val url = host + baseUrl + soql println("url: " + url) val request = new HttpGet(url) request.addHeader("Authorization", "Bearer " + accessToken) request.addHeader("Content-type", "application/json") val client = new DefaultHttpClient val response = client.execute(request) val handler = new BasicResponseHandler() val body = handler.handleResponse(response) return body }
Create main()
method
Instantiate SObject
with Account as the object name : sObject
.
Create a json
data string
Create a soql String with the query as shown below
val soql = """SELECT+name+from+Account"""
Call sObject.executeSOQL(soql)
object ExecuteSOQLQuery{
def main(args: Array[String]): Unit = {
val sObject = new SObject("Account")
val json = """{"name":"Account1"}"""
val soql = """SELECT+name+from+Account"""
val response = sObject.executeSOQL(soql)
println("response:" + response)
}
}
$ sbt compile $ sbt run
In this blog I showed you how to use Scala and access Salesforce data using REST. The sample code enables you to do Create, Delete and Query actions using Force.com REST APIs, and should get you and your team started quickly. Enjoy!
Rajdeep Dua is Director Developer Relations at Salesforce. He is passionate about helping developers learn about Cloud Computing and Salesforce. He has over 16 years of experience in Software Product Development and Developer Relations.