Years ago when Microsoft released it’s latest version of SharePoint Designer, it came with a few enhancements that really made building workflows with Designer more robust and efficient. One efficiency enhancement was the ability to copy actions, steps and even entire stages within the same workflow or even between workflows. Microsoft also allowed for the ability to move back and forth between stages instead of continuing down a parallel path (called a state machine workflow). While the addition of state machine workflows to Designer (previously only available in Visual Studio workflows) is great; in my opinion the best (by a very small margin) addition to Designer is the ability to call web services. As your queries get more and more complex however, knowing what is coming back into the workflow can be filled with frustration as you try to determine how to get the data from the response content. While I it isn’t a new concept, I wanted to discuss handling REST responses in SharePoint Designer workflows. Or at least how I do it. The method I use is pretty straight forward and very easy to implement.
The Scenario
Let’s start with a scenario that I have a list containing a series of approvers for an approval workflow. The names are SharePoint User\Group fields and the Title field is used to describe the department the users are approvers for. I am not doing it as a lookup field in this case as I want to keep my example as simple as possible while still illustrating how to accomplish the goal of this post. Here’s how the approver list looks:
Quick note: My examples in this blog post use SharePoint Online, but the same steps work in SharePoint 2013 and SharePoint 2016.
Handling REST responses in SharePoint Designer Workflows
Build a Test List
So the first thing you need to do is create new list. Add two new fields. Let’s call the first one ResponseContent and the second RequiredValue.
Add a Workflow to the List
Open up SharePoint 2013 Designer and create a new workflow against the test list you just created.
- Add a variable for the list name
- Create a dictionary with an entry for Accept and Content-Type. Both will have the value: application/json;odata=verbose.
- Next create an App Step (you don’t have to do this if it is just yourself testing, but I do it out of habit).
- Next we are going to add the Call HTTP Web Service action.
- For the purpose of this test we don’t have to capture all the data. We will be adding the request headers, creating a variable for the response content and the response code and setting the call URL. The URL you are going to build will have the following value:
NOTE: I am hard coding the title for the this example, but normally an item value would go there instead. - [%Workflow Context: Current Site URL%]/_api/web/lists/getbytitle(‘[%Variable:wfListName%]’)/items?$select=Approver/Name&$expand=Approver/ID&$filter=Title eq ‘Finance’
- Normally the REST call will just send back the ID of the user within the site’s User Access List. However, we want their name. To do that, we have to tell the REST call to dig a bit deeper on the Approver column which is why we add “$expand=Approver/ID” and actually request “Approver/Name” to be returned.
- Next we want to write the response code to the workflow log.
- Finally, we want to update the Test list with the response content from the API call. Simply update the ResponseContent field with the data from the REST call.
- Publish the workflow and Test.
The results of your call should be returned to the test list you created earlier.
Reading the Response
It really doesn’t matter if you are running SharePoint on-premises or SharePoint Online. Here’s why:
For SharePoint on-premises you are going to get a response like the following:
{"d":{"results":[{"__metadata":{"id":"Web\/Lists(guid'a97121d6-1f42-4d92-8b64-d8b26c230468')\/Items(1)", "uri":"https:\/\/<siteurl>\/_api\/Web\/Lists(guid'a97121d6-1f42-4d92-8b64-d8b26c230468')\/Items(1)","etag":"\"3\"", "type":"SP.Data.<ListName>ListItem"},"BusinessUnit":{"__metadata":{"id":"c1eefd00-05e5-4100-bc15-26f0c9a6d225", "type":"SP.Data.<sitecolumn>ListItem"},"Title":"<Item Title>"},"Approver":{"__metadata":{"id":"3ebf36d7-89cb-4361-8981-bc00341b324b", "type":"SP.Data.UserInfoItem"},"SipAddress":"<email address>"}}]}}
However, the same thing from SharePoint Online:
{"d":{"results":[{"__metadata":{"id":"9b3e9004-9606-426d-a63f-1a442b450f8e", "uri":"https:\/\/drevsponline.sharepoint.com\/_api\/Web\/Lists(guid'f25b29b1-13a6-4e77-a99f-19c24bbe4a89')\/Items(3)","etag":"\"1\"", "type":"SP.Data.ApproversListItem"},"Approver":{"__metadata":{"id":"48f0ec73-4ae8-48d2-8861-570a63af6fbf", "type":"SP.Data.UserInfoItem"},"Name":"i:0#.f|membership|spo_testuser@drevsponline.onmicrosoft.com"},"Title":"Finance"}]}}
Both will seem confusing to those who have never read a JSON reply yet. Another way to get the response is an application called Fiddler.
To some the Fiddler response is much easier to understand and actually translates nearly directly into the format you need to handle the response from:
The Fiddler and the SharePoint responses make more sense when you build out how the workflow handles gathering the necessary data from the response. I will cover this in the next blog post.
By the way, it may seem redundant to build my list solution and the Fiddler solution to determine the response. I have a couple of reasons for using the list method as well:
- Helps you to refine and test the string builder entry for the work flow. If your workflow is long, why go through the whole thing just to make sure your REST call is correct in the workflow. Simply use my solution above in a basic list to refine the HTTP call.
- Let’s you easily test reading from the response (covered in the next post).
- Not often, but there have been a couple of instances where the response to Fiddler has been different enough to the response to the workflow that I needed this method to work out how to handle the response.
My next post will handle how you can translate the above response to building the string to read the data from the JSON response.
Thanks for reading!!
Comments