We can use SharePoint Designer workflows to author an approval process. Sometimes the approval process can be complex where we need to create advanced workflows. In SharePoint 2013 workflows we can use HTTP web services and loops to assist such instances.
Recently I created an approval workflow to a library which stores document sets. Following is the pre-condition to the approval.
Each document set has two allowed content types named “Policy Document” and “Policy Checklist”. The approval process proceeds if the document set contain at least one document from each document set. Otherwise the approval process terminates.
Following are the questions we need to address
- How can we access documents within a document?
- How can we get the content type ID of each document?
We will call two web service methods to obtain relevant information and will use built in loop to assist the process. Following are the steps I used to answer above questions
1. Construct the server relative URL for document sets
Let’s assume our document set is located at “https://sp13/sites/dev/Shared Documents/DocumentSet1”. Below activity will remove “https://sp13/sites/dev/” component and assigns “Shared Documents/DocumentSet1” to a variable named “itemFolder”

2. Prerequisites to call SharePoint REST API
As I mentioned earlier, SharePoint 2013 workflows can call RESTful services by default. In this case we will use services provided in “_api/web”. Since those services provide xml output we have convert them to JSON.
To do that we will create a dictionary. For both “Accept” and “Content-Type” variables provide “application/json;odata=verbose” as the value

3. Call web service to get all items within the document set
To get items under a document set we will use GetFolderByServerRelativeUrl() method. Following is a sample service call
https://sp13/sites/dev/_api/web/GetFolderByServerRelativeUrl('Shared Documents/Set1')/Files
If you need further information on this method you can refer this blog post. To call the service using workflow we will use Call HTTP web service activity as shown below.
Following are the sub steps
A. When constructing the url, we will use the sever relative path created in step 1

B. Create an empty dictionary variable named JSONResults
C. Edit properties of the activity to assign “Header” and “JSONResults” dictionaries to RequestHeaders and ReseponseContent parameters.

Finally the activity looks like below

Unfortunately this service doesn’t return Content Type ID property. As a result we will get a property from this service which can be input to our second service to obtain Content Type Id. We will call the second service in step 8.
4. Store results to a separate dictionary called allItems

5. Get count of items to start the loop

6. Store variable to hold content type IDs

7. Create a loop to iterate each item we have in allItems dictionary
Create an integer variable named index.

Then we will get the ServerRelativeUrl property from the item and assign it to variable serverRelativeUrl

8. Call the second web service to get content type id.
Since “GetFolderByServerRelativeUrl()/Files” method does not return the content type of items. As a result we need to execute another service to do so. We will use the ServerRelativeUrl property returned from step 7 as an input to the second service
This time we will call GetFileByServerRelativeUrl() method. Following is a sample of the service call.
https://sp13/sites/dev/_api/Web/GetFileByServerRelativeUrl('/sites/dev/Shared Documents/Set1/3.txt')/ListItemAllFields
If you need further information on this method you can refer this blog post as well.
As we did for the first method we will call HTTP web service activity as shown below


9. Get ContentTypeId property of the item
This service returns just a single item. So it is easy to get the value

10. Create Boolean variables to store content type availability
Since we have two content types, we have two Boolean variables named “ct1IsAvailable” and “ct2IsAvailable”

11. Set Boolean value true if the content type was found

12. Specify Termination condition at the end of the loop

13. Conditionally allow or restrict the approval

14. Terminate the workflow

Summary
In the above article I explained how to use http web services available in “_api/web” within SharePoint 2013 workflows. A practical scenario was also explained where we need to check at least one document from each content type available in the document set.