REST
The REST Service Type is used to allow K2 to integrate with REST endpoints, by exposing a particular REST endpoint as a service instance and then creating SmartObjects that utilize the service objects exposed by the service instance.
The REST broker is unlike other service brokers in that it does not discover entities and methods of the LOB system (in this case the REST endpoint) when a Service Instance is registered. Instead, when registering the service instance, you must provide a descriptor file in Swagger format that describes the entities and methods in the targeted endpoint. This descriptor file will control how the Service Objects for entities and methods (paths) in the endpoint are generated. (For more information about Swagger see http://swagger.io/ and the REST Swagger File Reference Format topic.)
- KB001786: Resources for Working with the REST Service Broker
This article includes a list of resources and recommendations on getting or creating a Swagger file. - KB001757: Integrating a REST-based Service with K2
This article demonstrates an end-to-end scenario that involves exposing REST Endpoints provided by the Swagger PetStore example as wizards that can be used in K2 workflow design tools. - KB001758: Generating a Swagger Descriptor for REST-based Services using RESTUnited.com
This article describes how to use a tool (RESTUnited.com) to generate a Swagger descriptor file. This is useful if you do not control the source code of your API. - KB001869: How To: Generate a Swagger Descriptor for REST-based Services using Swashbuckle
This article describes how to add the Swashbuckle NuGet project to your API to generate Swagger. This is useful if you control the source code of the API. - KB001781: Using the REST Service Broker with Azure API Apps
This article describes how you can use the REST Service Broker provided by K2 to expose Azure API apps as SmartObjects
- See How To: Create a SmartObject to connect to a REST service for an example of using the REST service type and an advanced SmartObject to connect to a REST web service.
- See How to: use a REST Service-based SmartObject in a workflow loop for an example of using a REST-based SmartObject in a workflow Loop step.
Querying and submitting data using an Endpoint Service Type can be a complex issue. It requires a good understanding of data and how it is returned from the service call. It also requires understanding the serialization and deserialization methods that are intrinsic to the .NET Framework.
The main methods that are used with the endpoint services are Serialization and Deserialization. Simply put, these methods are used to send and store complex data. To Serialize the results of a service call means to represent it in a state that can be transferred and/or stored, such as in a database. To Deserialize that data is to turn it back into a state that can be consumed. These methods, while based on the .NET Framework for the purposes of the K2 Endpoint Service Type, represent a device-independent, cross-platform method of representing complex, relational data.
Prerequisites
To use a REST Service Instance you must first generate the Swagger descriptor file, and register an OAuth resource in K2 if your endpoint requires OAuth. For the sample PetStore.json file given later in this topic you do not have to establish an OAuth resource.
Service Authentication
All available Authentication Modes are supported by this broker. The Authentication Mode of the Service Instance should be set according to the authentication required by the endpoint. For example, if the endpoint supports static authentication then select the static authentication mode and provide a username and password.
If using the OAuth Authentication Mode, bear the following points in mind:
- You must create the OAuth resource type and resource before registering the service instance, since you will need to provide these values when selecting the OAuth authentication mode. For more information on how to do this, see the topic OAuth in this user guide.
- If you require OAuth authorization but do not wish to create an OAuth resource, you may be able to pass in a static authorization token in the HTTP header using the Default HTTP Request Headers Service Key. This type of functionality is dependent on the REST service and should only be used for development purposes.
- You do not typically need to specify an Audience for the OAuth resource unless you are using a Microsoft Online (Office 365) endpoint.
Service Keys (Service Instance Configuration Settings)
The following table lists the Service Keys, their default values and some sample values. The sample values use the PetStore service at http://petstore.swagger.io/. You can download a pre-defined descriptor file for this sample from https://help.k2.com/repository/data/json/PetStore.json.
Key | Can be modified | Data Type | Sample Value | Notes |
---|---|---|---|---|
Serialization: Include All Assembly types | Yes | True/False | True (Default value: True) |
Includes all available serialization objects regardless of usage in public methods. |
Default Http Request Headers | Yes | Text |
{"$type":"SourceCode.SmartObjects.Services.Endpoints.Common.HttpHeader[], SourceCode.SmartObjects.Services.Endpoints.Common, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null","$values":[{"$type":"SourceCode.SmartObjects.Services.Endpoints.Common.HttpHeader, SourceCode.SmartObjects.Services.Endpoints.Common, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null","Name":"Authorization","Value":"Bearer value"}]} *Replace the values with the token that needs to be passed. |
Used to supply default HTTP headers that should be added onto every HTTP request. This key is a name/value pair that is serialized using the HttpHeader system type as shown below in The HttpHeader Type section. An example of an HttpHeader value might be an additional authentication name/value pair required by the service. |
Descriptor Location | Yes | Text | https://raw.githubusercontent.com/K2Documentation/ K2Documentation.Samples.JSON/master/PetStore/PetStore.json (see a sample) |
Required. The location of the descriptor file. This must be a URL. See Descriptor File Considerations for more information about the location of the descriptor file. |
Names: Append Property Types | Yes | True/False | True (Default value: True) |
Includes the property type in parentheses after the complex property name. |
Break on Error | Yes | True/False | False (Default value: False) |
When True displays an error dialog if calling the service results in a non-success response. When False no error is displayed. In either case the HttpResponseCode return property contains any errors. |
Debugging Enabled | Yes | True/False | False (Default value: False) |
Displays stack trace information in dialog and error information. |
Include non Serialized Properties | Yes | True/False | False (Default value: False) |
If the value of this Key is set to True it will add non-Serializable properties on the Serialize method Input values. |
Certificate Search Value | Yes | Text | NameOfCertificate (sample) (Default value: null) |
The search value to use when looking for a client certificate. Filling in this config setting will cause the broker to expect to find a valid certificate at the specified location. An error will be thrown if a valid certificate is not found (this includes the case where a certificate is found, but the certificate is invalid due to expiration or lack of trust). Used in conjunction with the Certificate Search Method. Typically the certificate should be installed under the K2 Service Account user's CurrentUser\My store (CurrentUser\Personal).
|
Add HTTP Response Header Property To Methods | Yes | True/False | True | Adds an optional property to each method to allow for a list of HTTP Response headers to be returned from the service. |
Certificate Search Method | Yes | Text | FindBySubjectName (Default value: FindBySubjectName) |
This setting is only used when the Certificate Search Value setting is is set. This specifies the method with which to search the opened certificate store for the client certificate. There are a number of search options available including searching by name or thumbprint. Please refer to: |
Names: Use Method FullName | Yes | True/False | True (Default value: True) |
Uses the full name of the method including the property names and types. |
Add HTTP Request Header Property To Methods | Yes | True/False | True | Adds an optional property to each method to allow you to send HTTP Request Headers to the service. |
Serialization: Compress | Yes | True/False | False (Default value: False) |
Compress the serialization data for complex types. |
Authorization Header Format | Yes | Text | Bearer {0} |
Used to construct the Authorization header. Use the default valueBearer{0} if this service key is null or empty. |
Timeout (Seconds) | Yes | Text | 60 (Default value: 100) |
Sets the Timout value for the REST Endpoint service. |
Use legacy query string parameter encoding | Yes | True/False | False (Default value: False) |
Sets the encoding of query string spaces (" "). When set to False (default), spaces are encoded using the plus ("+") sign instead of "%20", which is a result in a change to the RestSharp library when encoding a space character. To use the legacy "%20" encoding for spaces, change the service key to True and refresh the service instance. |
Create swagger definitions object type as JObject | Yes | True/False |
False |
When set to True, allows users to specify that they want the swagger type object in the definitions to be created in K2 as a JSON object. This will allow for serialized values to be passed in as JSON instead of as a string. When set to False, serialized values are passed in as strings and quotation marks are escaped, and when the value is sent to the service it can't be deserialized correctly. |
Service Objects
Once an Endpoints REST Service Instance has been created, the entities and service operations described by the descriptor file are represented as Service Objects.
The Service Types are grouped into the following categories:
- Object Types: This folder contains all of your entities as you described in your descriptor file. Each entity and its associated properties and methods should be visible. If you are missing any properties or methods it means that the descriptor file is not complete.
- Service Operations: This folder contains any methods (paths) that are not associated with a particular entity. Service operations may work with one or more entities but are not specifically tied to any one entity. If you see methods in this folder that should be associated with an entity, check your descriptor file.
- System Types: This folder contains base types that can be used to serialize or deserialize method properties, parameters or return types.
The HttpHeader Type
The HttpHeader system type is a special type of service object that is used to serialize or deserialize name/value pairs for the Service Instance or for individual methods. To use this type you must generate a SmartObject from the service object and then call a method on the SmartObject. When specifying this header you execute the Serialize method on the HttpHeader object (which you can find in the System Types folder in the SmartObject) and use the serialized value. If you need more than one HttpHeader you serialize each name/value pair and then use the Serialize Add Item to Array method for each name/value pair that needs to be passed to the endpoint.
SmartObjects
K2 does not automatically create SmartObjects for the Service Objects in this service. SmartObjects can be automatically created by selecting the Generate SmartObjects for this Service Instance check box when creating a new Service Instance. Designers can use the SmartObject design tools to build advanced SmartObjects that leverage the Service Objects in this service. It is recommended to use the SmartObject design tools to create SmartObjects rather than generating SmartObjects, since this allows better control over the naming, behavior and design of the SmartObject and its methods and properties.
When working with SmartObjects it's important to know how properties are used for the service. For example, if you have a POST method that requires you to submit a complex object type (entity) you must first serialize that entity using its serialization method before you can call the POST method. The serialized string representing the required entity is passed as a string property containing a serialized object to the method. This method of representing complex types as serialized objects is common to many service brokers that K2 ships out of the box, so if you're already familiar with these principles you can apply them to the REST broker.
If you're not familiar with these concepts, use the example below that uses a sample Swagger Pet Store service.
Some points to bear in mind if you are working through this sample:
- Use the example PetStore.json descriptor file to register the Service Instance
- The Swagger PetStore service automatically deletes pets created as part of this example service so you should call the FindPetsByTags method soon after creating the pet, otherwise you may not find it if the method is called at a later time.
- The Swagger PetStore service changes as the development of Swagger continues. Examples used here and the structure of the service may not match what you see.
Using the Pet Store example, there is an AddPet method on the Pet entity that requires a Pet memo field to execute:
Executing the Serialize method of the Pet entity requires the following properties:
The Category, PhotoUrls and Tags properties are entities as well, so in order to call the Serialize method of the Pet entity you must first serialize those entities. Note that the descriptor file does not contain an entity for PhotoUrls since it is an array of strings. It is an optional property it is not included in the example.
The Serialize method of Category requires an ID and a Name:
Executing the method returns a serialized string which can then be used as the value for the Category property of the Serialize method of the Pet entity.
- Any field that is of type Memo typically represents a complex type that needs to be serialized.
- If a field can contain multiple items, such as Tags, two square brackets follow the entity name, e.g. Tags[]. This means that you must run the Serialize Item to Array method instead of the Serialize method.
-
If a serialized item is an array of items you would use the Deserialize Array or Deserialize Typed Array to extract values from the serialized string returned from the service.
When you have all of the serialized strings ready you can use them to create a Pet object, as follows:
Once you have the Pet object serialized you can pass that in to the AddPet method as a single input. Executing the method returns an HTTP response code of 200, confirming that the pet was added.
To find the ID of the pet you can use the FindPetsByTags method of the Pet entity. This method requires a serialized array of strings, so you use the Serialize Item to Array method of the String System Type to generate a serialized string:
You can then pass the serialized array in to the FindPetsByTags method as follows:
In the screenshot above, you can see that Bowzer was created with ID 1433767701761.
There are simple types (Id, Name and Status) returned by this method as well as complex types that are serialized. To deserialize these complex types, such as Category, you execute the Deserialize method of that entity. For example:
Lastly, you can create an advanced SmartObject that chains these serialize & deserialize methods. For more information about doing this, see Working with Endpoint SmartObjects.
For example purposes only, here are the following serialized strings used in the sample:
- Category for Serialize method of Pet: {"$type":"PetStore.Category, PetStore, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null","id":4857,"name":"Dogs"}
- Tags for Serialize method of Pet: {"$type":"PetStore.Tag[], PetStore, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null","$values":[{"$type":"PetStore.Tag, PetStore, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null","id":234234,"name":"MyPet"}]}
- Pet for AddPet method of Pet: {"$type":"PetStore.Pet, PetStore, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null","id":0,"category":{"$type":"PetStore.Category, PetStore, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null","id":4857,"name":"Dogs"},"name":"Bowzer","photoUrls":null,"tags":{"$type":"PetStore.Tag[], PetStore, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null","$values":[{"$type":"PetStore.Tag, PetStore, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null","id":234234,"name":"MyPet"}]},"status":"Available"}
- String Array for tags parameter of FindPetsByTags method of Pet: {"$type":"System.String[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089","$values":["MyPet"]}
Considerations
- Descriptor file location considerations
- If you are registering the service instance from a non-K2 server machine, the location of the descriptor file must be accessible from the K2 server. .
- The descriptor file is not cached by the server.
- The Authentication Mode used for the service instance is also be used to access the Description Location JSON file when that file is a URL. You may want to make sure that the file is located somewhere that does not require authentication to open.
- When using OAuth as the Service Instance Authentication mode, you may experience trouble when trying to reach the descriptor file. For example, if you use an anonymous file located in Azure Blob Storage while the service instance is configured to use OAuth, Azure Blob Storage will send back a 403 Forbidden error. This is because Azure does not recognize the authentication headers passed by the OAuth service instance security setting. To prevent issues like this, you can host the file in a provider that ignores the authentication header (such as Google FireBase or GitHub), or alternatively host the descriptor file in a location that uses the same authentication mechanism and provider as the service you are trying to reach. For example if your REST service is attempting to connect to the MS Graph API, the Swagger descriptor file should be located in a O365 location that uses the same authentication provider.
This file must be available at the specified location when the service instance is refreshed.
Paths in the Swagger file must be unencoded.
For more information about getting a Swagger file, see KB001786: Resources for working with the REST Service Broker
- The supported REST methods include:
- GET
- POST
- PUT
- PATCH
- DELETE
- Specific methods for some services may not be supported by the REST broker. If you suspect your method is returning types that K2 does not support, please troubleshoot the REST broker and the service using standard network tracing tools and trying to replicate the behavior in Visual Studio. If you suspect there's an underlying issue with the REST broker, please contact Nintex Customer Central
- The REST Broker currently only supports portions of the Swagger v2 specification.
- The REST Broker does not natively support File streaming. If you need to return files via the REST broker, return two properties: a string property for the filename, and a base-64 encoded string property that represents the file contents. You may need to adjust the REST service's source code to return files in this format.
- For additional troubleshooting tips, please see Troubleshooting the EndPoint Service Types.
- REST service instances cannot include periods in their name. For example, PfaK2SolutionName is correct, but Pfa.K2.SolutionName is not allowed.