Automation can be used in any application for any process. In most cases, our automations must interact with applications using the Graphical User Interface. While UiPath offers sophisticated UI detection facilities through its selector and anchoring mechanisms, these are not always guaranteed to work all the time.
For instance, when interacting with web applications, it is almost impossible to accurately predict how long the web app will take to respond to requests, as several factors out-with the developers’ control have an impact (connection speed, app responsiveness, other windows coming into focus etc.). Aside from that, our automation is at risk of breaking if/when the GUI layout is changed.
As a result, interacting with an API is preferable to interacting with the application front-end. When interacting with REST APIs, it is necessary to read and write JSON text as this is the typical means of communication between clients and servers in a RESTful architecture.
Building JSON strings for API requests can present somewhat of a challenge to automation developers, as there can be many JSON properties required for a request. Similarly, extracting information from JSON response strings can be arduous for the same reason.
In this article we’ll explore the problems with building JSON requests in automations, then discover a flexible solution by leveraging the .NET integration UiPath offers.
The Conventional Approach
When making POST, PUT or PATCH requests to a REST API, we must construct a JSON request body. This body contains all the information required to make our request valid and correct, according to the API specification. The number of key-value pairs our request body must have to make a valid request is variable, and so has the possibility to be quite large: this is the first of our challenges.
Consider the following example taken from the API for an HR application. To create a new employee, we must supply 27 properties in the body of our POST request. To construct the request body using UiPath activities, we would need 27 variations of the Invoke Method activity (one for each property, using the JContainer 'Add()' method in the ‘MethodName’ field). The expected JSON request body is shown in Figure 1 and an example of adding the first 4 properties to a JObject variable called requestBody inside UiPath is shown in Figure 2.
This is approach has several problems.
- To begin with, our workflow is polluted with lots of almost exact duplicates of a single activity, with only very minor differences in the activity parameters.
- On top of being repetitive, it makes our workflow somewhat unreadable as we now need a non-standard way to label what is being added to the JSON object by each Invoke Method.
- Finally, from a developers’ point of view, the process of adding each property to the request body is error prone as a single Invoke Method activity must be copied, pasted, relabelled, and its arguments changed to the required values.
Leveraging .NET integration
To improve upon this, we can utilize .NET integration with UiPath to build JSON more easily, flexibly, and readably. To do so, we will use the Invoke Code activity and some programming tricks to allow us to construct our objects without the need for calling the Add method.
To add properties to our JObject on the fly, we can declare it using the C# type dynamic, as demonstrated in Figure 3. Doing so defers static type-checking (verification checks that are performed before our automation is run) to be performed at runtime.
This means we can now create new properties for our JObject in a tidier, more comprehendible way. For example, to add the xName fields from the HR JSON snippet above (firstName, middleName, lastName, maidenName) we can do it as shown in Figure 4.
Figure 4. (Not the wrestling move)
Our new, programmatic approach lets us add any valid JSON data type to our properties. For example, we can add a JSON array to our properties using the .NET JArray type. We can even go as far as defining our JArray as we assign it to the property. If we had to add an array containing execution results, we could do so as follows.
The advantage of this approach is workflow brevity – a single Invoke Code activity versus multiple Invoke Method activities – and improved readability, as we can see exactly what is being added to our JSON object without the need to analyse Invoke Method activity parameters.
Once we’ve built our JSON object, we can pass it out of the Invoke Code in a few different ways. If sending an API request immediately after building our JSON object, we can convert the object to a string (since the HTTP Request UiPath activity expects a string in the ‘Body’ property), as shown in Figure 6. Alternatively, we can omit .ToString() and pass requestBody out as its native JObject – useful if we have further processing and want to add JSON properties later.
A word of warning
Although we can now build JSON quickly and readably inside UiPath, there is an important detail around the naming of properties that we should bear in mind.
If any of the property names (string values on the left-hand-side of ‘:’) in our objects contain characters that are not alpha-numeric or ‘_’, then we must add these properties using the Add() method. For example, if we were adding a datetime property named “top-up_date”, we must call Add() because the property name contains a hyphen.
As a useful footnote, there are best practice guides around JSON construction. The Google JSON Style Guide is one such guide and can be found here.
To conclude, building REST API request bodies in JSON need not be arduous anymore if we make use of some of the language features of C#.
To summarize what we have covered:
- Using an API is always preferable to using a GUI.
- Adding properties to JSON objects using UiPath activities (Invoke Method) is cumbersome and leads to unreadable workflows.
- We can replace all our Invoke Method activities with a single Invoke Code.
- Using the C# dynamic keyword to bypass static type checking, combined with the JObject .NET class, we can compact JSON object construction to as little as one UiPath activity.
- If any of our property names contain a non-alpha-numeric character (except ‘_’), we must add this property by calling the Add() function.
Having said that there are couple of details worth mentioning.
For starters, our techniques are only useful when sending requests and don’t help us in extracting information embedded in JSON from an API response. Happily though, there are other programming tricks we can use to help us do just that *cough LINQ *cough.
Perhaps a more significant detail is that our programmatic approach is only relevant to RESTful APIs communicating through JSON. If our automations had to communicate with a SOAP-based API, we would need to build our requests in XML.
Fortunately for us, we can use the XmlWriter class and again more programming trickery to help us in this endeavour, but that is a conversation for another time.
Join the newly formed UiPath Community Scotland Central Belt Chapter!
The newly formed UiPath Community Scotland Central Belt Chapter is an online and offline environment where RPA developers, professionals, and enthusiasts can meet each other and share experiences in the RPA industry, share our challenges and ideas and cooperate together to create a cluster of RPA expertise in the Central Scotland area.
If you are interested in joining and becoming a member of the UiPath community chapter or want to find out more information click here