Webservice

JMeter – Logging Into Salesforce for Automated Testing

by Patrick Connelly posted on June 29, 2017

I’ve written quite a few web services in Salesforce, and I’ve written about them a couple of times. And my love of testing is pretty well known. One thing that’s always been a problem is testing the web services in an automated fashion as a real consumer would. I’ve talked about manually testing them with SoapUI before, and while useful doesn’t fit into an automated process well. So let’s jump into the world of JMeter and how we can automate our web service testing for Salesforce.


Clean REST Endpoints in Salesforce

by Patrick Connelly posted on June 13, 2016

One of the things I love working on are webservices. However, one of the things I dislike about using SOAP is that using the endpoint isn’t as nice as it could be. This is something that has been addressed by how REST endpoints are interacted with. By writing clean REST endpoints, your users can easily understand what is going on under the hood

Clean REST Endpoints

What do I mean by clean REST endpoints? Let’s take a look at two possible URIs and see which ones are cleaner and easier to understand. For the examples below, we are going to have two URIs, one to get a case by case number, and one to get it’s comments

#Get case using url parameter
curl "$SFDC_URL/services/apexrest/v1/cases?number=012345"

#Get case comments using url parameter
curl "$SFDC_URL/services/apexrest/v1/comments?number=012345"

#Get case using number in url
curl "$SFDC_URL/services/apexrest/v1/cases/012345"

#Get case comments using number in url
curl "$SFDC_URL/services/apexrest/v1/cases/012345/comments"

While the parameters are perfectly acceptable, they are not pretty. Also, it is difficult as a programmer to know if the param you have add to the URI is number, or casenumber or what. So instead if we have clean REST endpoints, we have the case number as part of the URI and it is just more logical as to knowing how to get a specific case.


Web services development on Salesforce

by Patrick Connelly posted on March 09, 2015

Several years ago, I wrote a blog post on developing web services on Salesforce. When helping someone in the IRC channel with web services, I realize that the article was outdated and does not follow some of the design patterns that I have learned after spending a lot of time with web services

What are Web Services?

Let’s start with a little background. Web services are Apex code that you expose out and can consume with either SOAP or REST. Typically this is used to expose complex business logic in an easily consumable way. For example, you could use a web service to combine together an account with all of it’s contacts and return them in a single call. In this article we will be covering SOAP endpoints, but most of the principles also apply to REST endpoints.


Nulling fields in Salesforce with SoapUI

by Patrick Connelly posted on August 26, 2012

The Problem

The other day I came across a problem where sending in a blank field to Salesforce via SOAP was not nulling out the field. Instead, the enterprise WSDL was treating this as if nothing was sent, and therefore not updating the field at all. This make sense. If you were to send a sparse data structure over with only fields you want to update, you wouldn’t want to either have to provide the current value of every field or have them all nulled out. So, how do you null out a field with SOAP via the enterprise (or partner) WSDL in Salesforce?

The Solution

This is input is formatted for SoapUI, it may differ depending on the client you are using to send the SOAP message. The key take away is fieldToNull urn.

Lets start with a simple example of updating a field via the Enterprise WSDL

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:enterprise.soap.sforce.com" xmlns:urn1="urn:sobject.enterprise.soap.sforce.com">
   <soapenv:Header>
      <urn:SessionHeader>
         <urn:sessionId>${#Project#sessionid}</urn:sessionId>
      </urn:SessionHeader>
   </soapenv:Header>
   <soapenv:Body>
      <urn:update>
         <!--Zero or more repetitions:-->
         <urn:sObjects xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Contact">
               <urn:Id>${#Project#contactid}</urn:Id>
               <urn:CustomField__c>Yay! Data</urn:CustomField__c>
         </urn:sObjects>
      </urn:update>
   </soapenv:Body>
</soapenv:Envelope>

This will set the CustomField__c on the Contact to “Yay! Data”

To null out this field we simply send the field name as part of the fieldsToNull list

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:urn="urn:enterprise.soap.sforce.com" xmlns:urn1="urn:sobject.enterprise.soap.sforce.com">
   <soapenv:Header>
      <urn:SessionHeader>
         <urn:sessionId>${#Project#sessionid}</urn:sessionId>
      </urn:SessionHeader>
   </soapenv:Header>
   <soapenv:Body>
      <urn:update>
         <!--Zero or more repetitions:-->
         <urn:sObjects xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Contact">
               <urn:Id>${#Project#contactid}</urn:Id>
               <urn:fieldsToNull>CustomField__c</urn:fieldsToNull>
         </urn:sObjects>
      </urn:update>
   </soapenv:Body>
</soapenv:Envelope>

Salesforce and soapUI – Using the default query method

by Patrick Connelly posted on April 13, 2012

In a previous post I discussed how to test Salesforce webservices with soapUI. In this post I will show how to use the “default” methods inside the enterprise WSDL.

Logging In

First we need to login to Salesforce and get our session Id. Under the SoapBinding list, expand login and choose Show Request Editor. After opening the request editor we need to remove the extra headers we don’t need, and fill in our username and password.

Logging In

Then press the “play” button to send the request

Login request play button

Now in the resulting XML we can pull out our session Id

Session Id

And we can pull out our server Url

Server Url

Adding the new endpoint

If we create a new query request and remove the unneeded headers and insert our session Id and run the request you get the following error:

UNKNOWN_EXCEPTION: Destination URL not reset. The URL returned from login must be set in the SforceService

To fix this issue we need to add a new end point to our SOAP request. Using the server Url obtained during login we can add it to our request

New end point

And now we can rerun our new request with the correct endpoint

New end point

Conclusion

Unlike custom webservices which include the Salesforce endpoint as part of the WSDL the standard Salesforce enterprise WSDL only has the test or login url included. Because of this, we need to use the returned server url to set our end point.


Salesforce and soapUI — Testing WebServices directly

by Patrick Connelly posted on February 03, 2012

In a previous post I talked about writing webservices for Salesforce. In this post I’ll discuss how to test your webservice with soapUI without having to write any additional code.

Getting soapUI

You will need to install the Open Source version of soapUI from their ]sourceforge. Go ahead, I’ll wait…

Getting the WSDLs

Now that you have soapUI installed we need to download our WSDLs. You’ll need the Enterprise WSDL which can be found at Setup-Develop-API. And you’ll need the WSDL for your webservice which can be found at Setup-Develop-Apex Classes, then find your class and click the WSDL link next to it. I suggest downloading them into a WSDL folder just for organization.

Setting up soapUI

Now that we’ve got all of our parts we need to create a new soapUI project. If you are testing multiple webservices I suggest you only create one soapUI project and import the additional webservices into it. This will make updating the enterprise WSDL easier, and will make your life less stressful.

Right-click on Projects and select New soapUI Project and fill out the form with your information. Your intial WSDL should be the enterprise WSDL. You will at the very least want to have Create Requests checked. You can choose the other later if you want to.

New soapUI Project

After creating the new project you will see a section called SoapBinding with several methods below it. These are standard Salesforce methods that are provided by the Salesforce Enterprise WSDL. Let’s ignore these for right now, and import our webservice. To add a new WSDL right-click on the project name, Salesforce in our case, and select Add WSDL.

Add WSDL button

Then we want to choose our webservices WSDL

Add WSDL screen

Using soapUI

Now that we are all setup, let’s test our webservice. First we need to login to Salesforce and get our session Id. Under the SoapBinding list, expand login and choose Show Request Editor. After opening the request editor we need to remove the extra headers we don’t need, and fill in our username and password.

Login request

Then press the “play” button to send the request

Play button on login request

Now in the resulting XML we can pull out our session Id

Session Id

Copy the session Id and we will use it to make a request to our webservice. In the example below I am calling the search method on my CaseAPI. Again, we can remove almost all of the header out of the request. The only section we need to leave is the SessionHeader and SessionId.

Request with session Id

Then fill in the request to your webservice. This will all depend on how yours is designed. In the webservice call below, we pass in two context objects. One takes in an ssoName and the other takes in a searchString. Then as before click the “play” button and you’ll get your response back.

Conclusion

SoapUI is a great tool to help test webservices out. You can use it to build up tests, but that’s another post. I use it all of the time to verify that Salesforce is returning the correct data from my webservice instead of trying to write against the webservice and trying to determine if my client is messing up.


Creating Web Services in Salesforce

by Patrick Connelly posted on January 06, 2012

This article has been updated to show lessons learned over the past three years. The content of this article is still relevant, but is a little out-dated.

Preface

At my current job, we have several external systems that interact with Salesforce, and they do so through web-services. This document will cover what I have learned in regards to web-services, caveats with them and common pitfalls.

Overview

The goal of our web-services is to provide a single point of entry for each major object represented in Salesforce. A major object would be Account, Case, Case Comment etc. The reason this is differentiated is that for instance, Case Groups would under the AccountAPI since they are a minor object. Each web-service consists of two parts. First the actual web-service class which holds the externally facing methods and from which the WSDL is generated. The second part is that of the util class which holds all of the logic and is reusable.

Web-service class

APIUtils

This class contains several static variables, exceptions and most importantly the classes that are returned from the web-service

Static Variables

The static variables listed here are used to set the returnCode in the resulting return class. This helps to keep return codes consistent with what is expected by the calling app

Exceptions

There are two types of base exceptions in APIUtils

InvalidException

This is used for things that are passed into the web-service that are considered invalid. For example an invalid username passed in, or if the account does not match the requesting contact.

UnknownException

This is used when the requested object cannot be found. For example if the case 123456 was requested and was not found then this would be a_UnknownCaseException_

Generic Contexts

For most web-services, they will contain their own Context classes. But there are some context classes that are common and reusable. The primary one being the ContactContext. The ContactContext is often passed into the method to determine access level.

Returned Classes

These are abstraction classes usually representative of a Salesforce object.

  • Each field to be returned must be of type WebService
  • Each class should have Integer returnCode and String message to be passed back to the caller.
  • If the method is to return a List a wrapper class of APIObjects should contain returnCode, message and a List of Objects. [Example below]
  • Each class should have a constructor to aid in creation. This will save time in the long run and will make writing tests 1000 times easier

Note: You could probably throw exceptions out to the calling service instead of setting a returnCode. I think that setting the returnCode instead of throwing an exception makes it easier for integration since the integrator does not need to know the exceptions.

ObjectAPI

This class should be written primarily as a wrapper class for the Object’s util class

Specific Contexts

If contexts are needed and they will only be used by this API, then they should be included directly in the API file

  • Each field must be of type WebService
  • Each class should have a constructor to aid in creation
  • Do not assume that variables in contexts will be set

Methods

Each method should be disparate function of work and contain minimal logic. These methods should call the required Util methods, transform data, catch exceptions and set returnCode/messages

  • Method must be of type WebService
  • Method must be static
  • Method should return an APIObject
  • Method should set the returnCode and the message of the APIObject
  • All calls should be in a try-catch block so that no exceptions are leaked

ObjectUtils

This class should have the majority of the logic. The methods in this class should follow the idea of Samurai Programming. Samurai Programming means the method should “return successful or not at all.” This means instead of returning null if an error happens (if the method should return something ie getCase) then the method should throw an exception.

  • Most methods will be static
  • Methods should throw an exception if the parameters are set incorrectly
  • SOQL queries that are single lines should have their exceptions caught, reported then throw the appropriate exception. For example if we are selecting a single Case using Case c = [ select ... ] then we should catch the exception in case the query fails, and then thrown an UnknownCaseException.

Caveats

  • Declaring a class as virtual and then implementing that class to try to have global variables that all classes get do not work. The fields will not show up in the generated WSDL