URIs for REST Services
RESTful services expose each method of a SmartObject as a separate endpoint. This means you will access the methods by submitting requests to a specific URI, and include query string parameters to specify how and what data is returned.
The basic URI of these services is as follows:
{Service Root URI}{Service Path}?{Query Options}
The image below illustrates how a REST service endpoint is constructed:
As with the WCF services, the Service Root URI is defined by the <smoServices> section of the K2HostServer.exe.config file. The Service Path is defined by the SmartObject’s location in the category system (or by the Alias value specified in the K2HostServer.exe.config file) and each method for the SmartObject is appended to the service path to create separate endpoints for each SmartObject method.
K2 will replace other special characters in the URI with an underscore by default. You can change the replacement character by changing the value of the specialCharacterReplacement configuration item in the smoServices section.
Replacement Characters
To prevent the need for double escaping, K2 accepts the following replacement characters when passed as part of the Service Path. There is no need to use replacement characters when passing values as Query Options.
- _U_ = _ (Underscore)
- _S_ = / (Forward Slash)
- _B_ = \ (Backslash)
- _C_ = : (Colon)
- %20 = {space} (standard URL escaping)
URI Structure
Service Root URI
Structure: {Scheme}{Server}:{Port}{Service Root}/{Service Type}
This part is the "root" URL that exposes the various, SmartObject-specific endpoints.
- Scheme = http:// or https:// if SSL is enabled
- Server = Server Name or Host Header of web site hosting K2 services
- Port = Port of web site hosting K2 SmartObject Services, the default is 8888
- Service Root = service endpoint exposed by K2 SmartObject Services. The default is SmartObjectServices
- Service Type = for RESTful services, the default is REST
The Service Root URI (up to Service Type) is configured via the scheme, server, port and serviceroot settings in K2HostServer.exe.config.
Service Path
Structure: {CategoryPath}{SmartObjectName}{MethodName}
This part identifies the SmartObject and the SmartObject method being targeted.
- CategoryPath = the path to the category that contains the SmartObject
- SmartObjectName = the display name of the SmartObject to call.
- MethodName = the display name of the SmartObject method to execute
The Service Path is inferred by K2 through the location of the SmartObject in the Category System, the SmartObjects' display name and the SmartObject Method Display Name.
Query Options
The query options are used to provide values for the parameters expected by the SmartObject method, to pass in filter expressions or, in the case of list methods, to specify the return format of the data. Multiple parameters can be combined using & between the parameters.
Structure:?{System Query Options }&{Custom Query Options}
- System Query Options – optional query string parameters that can be used to control the format and amount of data returned. The System Query Options start with a $ and are typically available for all URIs that return data from List methods.
- Custom Query Options = are additional parameters that are specific to the SmartObject method exposed on that EndPoint.
System Query Options
System Query Options are query string parameters that can be used to control the format and amount of data returned. System Query Options start with a $ and are typically available for all URIs that return data.
Query Option | Values/Sample Values | Notes |
---|---|---|
$format |
xml atom json |
Specifies the format to return the results. Uses default (XML) if omitted. The $format parameter is only available for List methods Example: https://api.denallix.com:8888/SmartObjectServices/REST/K2 Examples/Employee/Get List?$format=atom |
$skip | Integer, e.g. 0 (default), or N | Specifies N number of records to skip. Uses 0 when omitted, which will return all records. The $skip parameter is only available for List methods Example: https://api.denallix.com:8888/SmartObjectServices/REST/K2 Examples/Employee/Get List?$skip=2 |
$top | Integer, e.g. 0 (default), or N | Specifies the first N records to retrieve. Uses 0 when omitted, which will return all records The $top parameter is only available for List methods Example: https://api.denallix.com:8888/SmartObjectServices/REST/K2 Examples/Employee/Get List?$top=5 |
$ filterXml | An XML string representing the filter to apply to the method results. | Specifies the SmartObject filter to use to limit the results. Uses no filter when omitted, which will return all records. The $filterXml parameter is only available for List methods Example: https://api.denallix.com:8888/SmartObjectServices/REST/K2 Examples/Employee/Get List?filterXml=<filterexp><equals><left><propertyexp name="Last_Name" sotype="Text"/></left><right><valueexp sotype="Text">Cowan</valueexp></right></equals></filterexp> |
FilterXml
K2 SmartObject Services utilizes the capabilities of the SmartObjects Filter Framework to enable filtering of your List based results for REST endpoints. The filterXml query option takes a single string parameter which is the filter represented as XML.
Below is an example of a filterXML value where we defined a filter to return only Employees where the Last_Name property is equal to "Cowan":
You can create the filter XML by hand, or use the SourceCode.SmartObjects.Client.Filter object in the SourceCode.SmartObject.Client.dll assembly to build up the filter and calling the GetFilterXml() method. This is also a useful approach if you want to obtain a sample XML string to begin with and then extend on further with manual editing.
- Add a reference to SourceCode.SmartObjects.Client.dll
- Import the following namespaces:
- SourceCode.SmartObjects.Client.Filters
- SourceCode.SmartObjects.Client
- System.Xml
- Create a method that uses the object model to build the filter. An example code snippet is shown below:
SourceCode.SmartObjects.Client.Filters.Equals lastNameEquals = new Equals();
//set the system name and data type of the SmartObject property that will be used in the filter
PropertyExpression lastNameExpression = new PropertyExpression("Last_Name", PropertyType.Text);
//set the value and data type of the value that will be used in the filter
ValueExpression lastNameValue = new ValueExpression("Cowan", PropertyType.Text);
//set the left and right side of the equals expression
lastNameEquals.Left = lastNameExpression;
lastNameEquals.Right = lastNameValue;
//create a filterexpression object and pass in the filter
FilterExp filterExpression = new FilterExp(lastNameEquals);
//serialize the expression as a string of XML
XmlDocument filterXml = filterExpression.GetFilterXml();
return filterXml.InnerXml;
The resulting XML for this method would resemble the following (formatted for clarity, if you were to pass this filter in, this value would be one long line of XML:
<equals>
<left>
<propertyexp name="Last_Name" sotype="Text"/>
</left>
<right>
<valueexp sotype="Text">Cowan</valueexp>
</right>
</equals>
</filterexp>
Building the XML string using the SmartObject Services Tester Tool
You can build the XML string with the SmartObject Services Tester Tool (%PROGRAMFILES%\K2\Bin\SmartObject Service Tester.exe).Execute a SmartObject that has a list method. In the List Method Options, click the Set button in the Filter section to open the SmartObject Filter dialog.
Build your filter and then copy the XML representation of the filter to a text editor. Edit the XML and make sure you remove line breaks so that it’s a single line, and then add the <filterexp></filterexp> container tags as shown in these samples:
Sample XML
Comparison Operators and Functions.
Equals
<equals>
<left>
<propertyexp name="Last_Name" sotype="Text" />
</left>
<right>
<valueexp sotype="text">Cowan</valueexp>
</right>
</equals>
</filterexp>
Greater Than
<greaterthan>
<left>
<propertyexp name="Age" sotype="Number" />
</left>
<right>
<valueexp sotype="text">1</valueexp>
</right>
</greaterthan>
</filterexp>
Less Than
<lessthan>
<left>
<propertyexp name="Age" sotype="Number" />
</left>
<right>
<valueexp sotype="text">1</valueexp>
</right>
</lessthan>
</filterexp>
StartsWith
<startswith>
<left>
<propertyexp name="Last_Name" sotype="Text" />
</left>
<right>
<valueexp sotype="text">C</valueexp>
</right>
</startswith>
</filterexp>
EndsWith
<endswith>
<left>
<propertyexp name="Last_Name" sotype="Text" />
</left>
<right>
<valueexp sotype="text">an</valueexp>
</right>
</endswith>
</filterexp>
Contains
<contains>
<left>
<propertyexp name="Last_Name" sotype="Text" />
</left>
<right>
<valueexp sotype="text">Smit</valueexp>
</right>
</contains>
</filterexp>
IsNull
<isnull>
<property>
<propertyexp name="Last_Name" sotype="Text" />
</property>
</isnull>
</filterexp>
Logical Operators
And
<and>
<left>
<contains>
<left>
<propertyexp name="Last_Name" sotype="Text" />
</left>
<right>
<valueexp sotype="text">Smit</valueexp>
</right>
</contains>
</left>
<right>
<endswith>
<left>
<propertyexp name="Last_Name" sotype="Text" />
</left>
<right>
<valueexp sotype="text">an</valueexp>
</right>
</endswith>
</right>
</and>
</filterexp>
Or
<or>
<left>
<contains>
<left>
<propertyexp name="Last_Name" sotype="Text" />
</left>
<right>
<valueexp sotype="text">A</valueexp>
</right>
</contains>
</left>
<right>
<contains>
<left>
<propertyexp name="Last_Name" sotype="Text" />
</left>
<right>
<valueexp sotype="text">B</valueexp>
</right>
</contains>
</right>
</or>
</filterexp>
Not
<not>
<predicate>
<equals>
<left>
<propertyexp name="Last_Name" sotype="Text" />
</left>
<right>
<valueexp sotype="text">Smit</valueexp>
</right>
</equals>
</predicate>
</not>
</filterexp>
Expressions
PropertyExpression
ValueExpression