This page describes the steps for calling a web service using the REST protocol. This page also gives you background information on how web services work within Blueriq.

There are multiple possibilities in Blueriq to define the data that is sent to and from REST services. The most common type of communication for REST is JSON, but Blueriq does support XML based REST messages as well. Both JSON and XML based message structures can be imported in Blueriq using the OpenAPI import or XSD import which significantly speeds up the development process.

The example in this guide uses an import of the Petstore. The Petstore is a sample API designed to simulate a pet shop management server. It provides access to Petstore data through a series of API calls. The API is organized into three endpoint categories: Pet, Store, and User. The documentation of this API can be found here: https://petstore3.swagger.io/. In this guide, we will only use the category named Pet. This will result in the example application "Petstore"

Pet store Example

This example project shows how the add, list, update and delete operations can be consumed with a Blueriq application.

REST 

Petstore.package.zip

1. Module structure

Strictly, there is no need to seperate the modules. However, as a best practice, we will separate our domain models by using a seperate module for the web service and a data mapping to exchange data between the business application module and the web service module. 

The REST call will be initiated by a service call of type AQ_RestServiceClient which is defined in the business application module of type interaction module. This service call has a reference to the REST service, which is used for setting up request and response parts of a REST service. A REST service may contain one or more domain schema's or schema sets. The REST service is defined in the web service module (which is also an interaction module). We will also need a data mapping which exchanges the data between the business application module and the web service module. This data mapping is defined in a configuration module.

2. Web service module

2.1 OpenAPI import or manual option

Blueriq will automatically generate the elements you need in the web service module including the module itself using an OpenAPI file about the web service that you want to call. This saves a lot of time and is less error prone.

You may however need to make some extra adjustments after importing an OpenAPI document, contrary to a WSDL which is more neatly defined.

To import an OpenAPI file:

  1. Select a repository and branch in the navigation panel and open the context menu () of the selected branch.
  2. Select "Import OpenAPI definition".
  3. Now, an OpenAPI file needs to be provided. You can choose between two sources that need to be a valid OpenAPI 3.0 or 3.1 file in JSON or YAML format: 
    1. Upload from a local file: You can select a file from your local storage. 
    2. Import from a URL: Alternatively, you can provide a direct URL link to the OpenAPI file for import and select "Fetch from URL". For example: https://petstore3.swagger.io/api/v3/openapi.json. Or you can use the OpenAPI feed of a Blueriq webservice. Read here how to get its URL.  
  4. Select the project and module in which you want to import the definition.
  5. Proceed to the next step to select which operations you wish to import.

    Certain features described in a valid OpenAPI file may not be supported by Blueriq. During the import process, unsupported features are identified for each operation and are ignored where applicable, allowing to import most aspects even in the presence of unsupported aspects.

  6. After selecting "Import", all generated elements will be saved and the newly created REST service elements will be opened automatically

Optional: to make the application more robust, we could optionally clean up unused elements from the domain schema. In our example we only use the id, name, and status. By removing the other parts such as category and tags from the domain schema(s), these parts are ignored and can therefore not fail if the structure of the actual message differs from the expected message.

You can also create the elements in the webservice module manually. 

2.1.1 Domain schema

The domain schema lets you define a representation of the elements in the application, and that is used for the communication with a web service. The purpose of this representation is to define what items are needed to accurately describe an element (for example the representation of person is his first name, followed by his second name.). You can see the domain schema as a sort of contract of the communication. You start with an entity that represents the begin and the end of the message. For every attribute/relation you can select a name, what datatype it is, if it is required within the message and if it is multivalued. This contract should be set up to reflect the message that is sent, but it can be different to the internal Blueriq domain. For instance, your contract uses a multivalued attribute. Your application always has one value for this attribute however, so it is not multivalued. When sending a message, it is no problem to insert a single-valued attribute in a multivalued entry in the domain schema. It will just be sent as a list with only one entry. You have to be careful if it is the other way around, storing a list with possibly more values on a single valued attribute will not work.

You might notice that the domain schema that you define is rather similar to the domain in Encore. This is certainly true. Situations when you deviate from this is when only a subset of information is needed (summaries), or if you have control attributes that are not interesting for the communication.

An important point to note is that the domain schema is independent of the language that is used for the communication, and projects can add implementations of any representation not covered out-of-the-box (out of the box we offer JSON and XML). Blueriq uses the domain schema that you define in Encore as basis to create a message to a web service or to read a message from a web service. Using the domain schema Blueriq generates a JSON or XML message in a straightforward way during runtime. To inspect the translation to JSON, click the "JSON preview" button in Encore. 

Beware of case sensitivity in the JSON or XML message.

2.1.2 REST service: properties

After creating a new REST service in Encore, you need to specify the properties of the REST service in the properties panel. 

  • The direction of a REST service indicates how this REST service will be used. In this example, we want to call a REST service, so we set the direction to "Outgoing." "Both" can also be used and can be convenient if both the calling and receiving applications are built in Blueriq and use a shared library.
  • The location is the base URL. You can already specify fragments and arguments here, but then you cannot change them later. For example, check https://soa.smext.faa.gov/asws/api/airport/status/IAD?format=xmlIn this case, airport, status and IAD are dynamic fragments and can change, depending on input by the user. You would only use https://soa.smext.faa.gov/asws/ as location in this case. 
    • Beware that the location can be set in the REST service, service call, and application.properties, in which the location specified in the REST service is the lowest and application.properties is the highest in the hierarchy.
  • The communication type can either be a Domain schema, or an XSD schema set. You have to choose one XSD schema set here that has to include everything for the entire web service. In contrast, by choosing a domain schema, you will later choose what domain schema to use for every separate method.

2.1.3 REST service: operations

You can specify as many operations as you need, by pressing on the "Add operation" button. Give every operation a unique name. After adding an operation, the request and response expansion panels will appear. 

2.1.4 REST service: request 

  1. Select a singleton entity in which you store data concerning your request, this is used for:
    1. Dynamic fragment attributes
    2. Dynamic argument attributes
    3. Header attributes
    4. The body relation to the root entity of the domain schema / schema set
  2. For outgoing REST calls, Blueriq supports 5 different HTTP methods: GET, POST, PUT, DELETE, and PATCH. In our example, the web service works with the GET method. This method does not alter the state of the web service and just asks for information. 
  3. Here the URL is shown that will be called. Items within {} are dynamic and determined at runtime.
  4. You can add static fragments which are always the same.
  5. You can also add dynamic fragments which are filled by attributes of the request entity. 
  6. You can specify arguments of your request the same way.
  7. You can also send a message to the REST web service as part of the HTTP headers. Request headers are more often used with POST and PUT methods. This procedure is the same as for the response of the message that you find just below here.

Some web services work with optional fragments. There is currently no way of defining optional fragments in this screen. The solution is to create a fragment attribute that concatenates different fragments using an expression.

For example: Request.PostalCode + ISUNKNOWN("/" + Request.HouseNumber, "").

2.1.4 REST service: response

Now you can specify the format of the response message. If you need to set headers, then you can do so at in the same way you set arguments or fragments for the request. For example, you can store the status header in the profile, so that you can show a different message to the end user depending on the status code (e.g., 'Try again later' when the web service had a time-out). How this could look like in Encore is shown in the screenshot below.

If you need to send information in the body of the message, for example with a POST message, then you can specify this now. This screen looks different depending on whether you send information using an XSD schema set or a domain schema.

We explain the XSD schema set first. First choose which entity will be sent ("Body element"). Fill in the name of the relation between your singleton response entity and your data entity. (Custom Schema) Elements are ways to fill in your schema in a different way other than with data from your profile. It is not needed at the moment (An example is a justification tree).

When using a domain schema, then simply select the domain schema that you want to use to send information. Furthermore, you have to select a body relation. This is a relation between the singleton response entity of your message and the entity that is chosen as the root entity in your domain schema.

The Response Data entity represents your complete message, including headers. The data that is sent, called the body, starts with the entity chosen as root element in the domain schema. Therefore, there should be a relation between the entity representing the message, and the entity representing the body. This relation should be selected at Body Relation. The message entity should be singleton.

 2.2 Authentication

During the OpenAPI import, authentication is ignored, so it has to be configured manually if there is any authentication applicable for the web service that you are calling.

There are multiple different types of authentication, for example: 

  • For basic authentication you can use the username and password field in the service call in the next chapter, or it is even better to pass the credentials through via the connection properties in the application.properties file.
  • The pet store example works with an api key that has to be sent in the header of the request. To do so, add a header named "api_key" to the request of the applicable operations in the applicable rest service ("Pet"). You will have to add an attribute for this which in the request data entity ("Request"). In this example, we can use a constant default value: "special-key".
  • Using OpenID connect, read more about it here: 5. AQ_RestServiceClient

3. Business application module

3.1 Create a service call

In order to call a REST web service, service call of type AQ_RestServiceClient needs to be created and placed in a in a flow for each operation that you want to consume. 

For our example, the parameters of the service call for the addPet operation look like this:

When the runtime stumbles upon an error during execution of the AQ_RestServiceClient, there are several options to handle this:

  • The exception exit can be used to handle exceptions such as a failing data mapping, or a response body that doesn't match the domain schema.
  • Use the exit events to handle timeouts, client errors (http status code 4xx), and server errors (http status code 5xx).
    • If there is a need to distinguish on a more specific http status code than the aforementioned ranges, you can use the header in the REST service to map the status code with the name "Status" to the profile.

3. Configuration module 

3.1 Create a data mapping

To exchange data from the profile between the business application module and the web service module, a data mapping needs to be created.

For the pet store the data mapping is relatively straightforward. For each operation, a data mapping is created with BusinessApplication as source module and WebService as target module. 

The AddPet operation maps the instance of the newly to be added pet with its attributes Id, Name, and Status of the new pet to the entity Pet in the target module.



Web service definitions may change over time. To be able to easily update this web service definition, it is a best practice to put an empty module on top of the module with elements that are created during the OpenAPI import. Then refer to this empty module as the target module of the data mapping. You can now easily replace the module during a new import with the updated definition.

Now there is one more thing we will use the data mapping for, that is setting the body relation in the web service module. E.g. the relation between the request data entity (Request) and the root entity of the domain schema (Pet). The runtime will throw an error if this relation is unknown. In the example, we use the Control entity in the business apllication module for this. 

  • No labels