REST Capabilities In Integration Server

There are various ways in which you can consume and expose REST APIs in Integration Server. In this article, we will look at how an Integration Server solution can expose existing services as REST APIs.

----------------------------------------------------------------------------------------------------------------------------

Note:

Integration Server provides two versions of REST interfaces:

  • REST v2 (Recommended)
  • Legacy REST (Deprecated)

REST v2 interfaces are an enhancement over the legacy REST interfaces. Among other things, REST v2 interfaces enable you to define custom URLs and use the URL templates and custom names for REST resources. This article explains how to use the REST v2 interfaces.

In Integration Server, you can expose existing services as REST APIs using a Swagger 2.0 document.

-----------------------------------------------------------------------------------------------------------------------------

In IS, there are two ways of creating a REST API:

  • Resource first
  • Swagger first

Resource First Approach

In this approach, you create resources in an existing solution and combine one or more of those resources to create a REST API descriptor. You can then generate a Swagger document describing the REST APIs from the REST API descriptor.

Swagger First Approach

This approach is basically a contract-first approach. In this approach, you import an existing Swagger document into Integration Server. Integration Server generates the assets required for the REST API defined in the Swagger document. These assets are document types, IS services, REST resources (REST v2), and the REST API Descriptor (RAD).

Components of Integration Server REST APIs

An Integration Server solution that consumes or provides REST APIs has the following components:

  • Document Types
  • Services
  • REST (v2) Resources
  • REST API Descriptor (that includes a Swagger file)

These components are described in the following sections.

Document Types

IS document types contain representation of the resource data, for example, the REST API’s parameters and responses. Integration Server defines these document types as part of the signature of  the REST services.

Services

IS service such as flow services, Java services, C services and Adapter services contain the business logic for accessing the resource data. Typically one REST URL maps to a single service with a defined input and output. Services are configured in the REST resources.

REST Resources

A REST v2 resource in Integration Server includes the name of the REST resource, URL templates for accessing the resource, the mappings between the URL templates, HTTP methods and the IS service.

URL Templates

A URL template is a construct that enables you to specify a URL including parameters that must be substituted before the URL is resolved. A URL template is only a part of the actual URL. Each URL template is mapped to an HTTP method and an IS service. A combination of URL template and HTTP method becomes a unique operation for the resource. You can specify multiple URL templates for a single resource. Following are examples of URL templates and their corresponding runtime URLs:

URL Template Runtime URL
/product/{pid} /product/101
/product/{pid}/orders /product/101/orders
/product/findByName /product/findByName

In the examples above, the parameters are specified within curly braces and are called path parameters. At runtime, a path parameter is replaced by the actual value and sent by the client. The REST v2 resources are configured in the REST API descriptor. A REST API descriptor combines one or more resources that are exposed as a REST API. A REST API descriptor includes certain configurations that are applied to the full API and not individually to the operations or resources.

URL templates in a REST v2 resource must be unique and unambiguous. This ensures that a single operation always points to a single service. For example, the following URL templates are ambiguous,

Ambiguous

/product/{pid} /product/101
/product/{productCode} /product/101

If you try to access a product by productId or productCode, the runtime URL cannot be mapped to a single URL template as both are matched, hence ambiguous. IS validates the ambiguity when adding the URL templates.

Unambiguous

/product/{pid} /product/101
/product/code/{productCode} /product/code/101

Unambiguous but same runtime URL

/product/{pid}/category/{catId} /product/PD1/category/CD1
/product/PD1/{category}/CD1 /product/PD1/category/CD1

The above two URL templates are not ambiguous, but the runtime URL is same. IS resolves this case by matching the static part of the URL template before the path parameter. Since both URL templates are matched, IS matches the static part first which is /product/PD1 in the second URL template and hence the service mapped to the second URL is invoked.

----------------------------------------------------------------------------------------------------------------------------

Note:

When REST v2 resources are added to a RAD, the ambiguity for URL templates is checked since two REST v2 resources may have URL templates that are same or ambiguous.

----------------------------------------------------------------------------------------------------------------------------

REST API Descriptor

The REST API Descriptor (RAD) is an IS asset that describes the full REST API. A RAD may include one or more REST v2 resources. You can also define which transport protocols can be used to access the API in the RAD. Various content types that define the request or response format can be configured for the whole API or individually for an operation. A RAD also defines the security definitions that are available for the REST API and then defines the security schemes for each operation. So, a RAD provides the complete information about the API in the form of a Swagger document. This Swagger document can be accessed through a URL in either JSON or YAML format.

Base Path

The base path (basePath) in a REST API is that part of the URL which comes after the server information and before the URL template. The base path is a part that is common for the API and also a handle to the RAD so that the request is directed to the correct service. The default value is /rad/<nsName of RAD>. “rad” is a directive in IS which routes the REST request to the REST API descriptor (RAD).  For the REST request to leverage RAD capabilities, the request should be directed through the RAD. Since the default value of the basePath is not user-friendly and exposes IS namespaces, you can change it to a meaningful value. When the basePath is changed, IS automatically creates a URL alias.

------------------------------------------------------------------------------------------------------------

Note:

You must use the “rad” directive for REST v2 resources.

-------------------------------------------------------------------------------------------------------------

Notations

<scheme> http or https
<host>

Server:port

For example, myserver:5555

<basePath> /orderapi
<resource-path> /product/{pid}
<Runtime URL>

<schema>://<host><basePath><resource-paths>

For example, http://myserver:5555/orderapi/product/1

Adding REST APIs to an IS Solution

Swagger First Approach

Using this approach, you can create a REST provider from a REST API that exists as a Swagger document. To achieve this, you first create a REST API descriptor using the Swagger document. The Swagger document can be a file in the local system or a URL hosted on a remote server. It can also be on the API Portal.

Let's take the example of a REST API "orderapi". Here the Swagger document is created by other tools.

When this Swagger file is imported by creating a REST API descriptor, the following assets are generated:

RAD

In the above example, storeAPI is the REST API descriptor. The RAD General tab displays the values such as info, basePath, and schemes from the Swagger document. The only value different would be for the “host” which is set to the server host and port on which the Swagger is imported.  You can modify this field to change the production value.

REST v2 Resource

The Swagger specification does not define a resource and hence the resources generated in IS are based on two options:

  • Swagger path
  • Tag

In the above example, the option is a Swagger path and so we see “order”, “product” and “products” as REST v2 element names which are derived by modifying the <resource-path> value to have an IS supported element name.  The URL templates are added according to the path in the Swagger document. The REST v2 resources are as follows:

REST v2 Resource URL template HTTP Method Mapped Service
order /order POST swaggerFirst.storeAPI_.services:placeOrder
product /product/{pid} GET swaggerFirst.storeAPI_.services:getProductById
products /products GET swaggerFirst.storeAPI_.services:getAllProducts

Refer to Option to generate Resources based on Tags section to generate the REST v2 resources based on tags.

Services

Let’s get into the details of the Swagger path.

Each path has an HTTP method. The combination of path and HTTP method is an operation. There is an operationId and the value of it is used as the mapped service name. If the operationId does not exist, IS generates the service name.

Each operation has parameters and responses.  The parameters are translated as input to the mapped service and response is translated as output to the service. For the /order POST operation, the parameter is a body type with reference to the “order” definition.

Document Types

For each definition, a document type is generated containing the fields based on the definition properties. In this example, the service placeOrder contains the signature shown in the following image.

The integration developer must provide the implementation in these services to complete the REST API.

Option to Generate Resources Based on Tags

When you import a Swagger document and select the option to generate resources based on tags, IS creates the REST v2 resources based on tags. In this example, we can see that ‘/order’ POST operation has a tag "order" and ‘/product/{pid}’ GET and ‘/products’ GET both have tag “product”. So IS creates two REST v2 resources, ‘order’ and ‘product’. “order” resource has one URL template ‘/order’ and “product” resource has two URL templates as below.

If the tag does not exist for an operation, a default tag named as “default” is assumed and the REST v2 name is set to default. All operations without a tag are included here.

The other assets are same as the option to generate resources based on paths. There is no runtime difference between the two options. The two options are provided so that you can group the paths in the most meaningful way for the REST API. The generated Swagger document is also the same.

Runtime Testing

Test the REST API using “Swagger UI” view in Designer or any other REST client by invoking each URL with various input combinations.

Compute the <Runtime URL> from the Swagger document for each entry of the path using the notations defined above. For the ‘orderapi’ Swagger:

The content-type and accept-type are set as “application/json”.

The following runtime URLs should be tested:

POST http://myserver:5555/orderapi/order

Here, there is a body parameter defined, and so with the request, send the body as:

{
  "quatity": 0,
 "productId": "string",
  "orderId": "string",
  "customerId": "string"
}

------------------------------------------------------------------------------------------------------------------------------------------

Note:

The body parameter name is “order”, however when sending the request, the name should not be sent.

------------------------------------------------------------------------------------------------------------------------------------------

GET http://myserver:5555/orderapi/product/1

Invoking this will provide the following response:

{
    "pid": "1",
    "price": 100.5,
    "productName": "toy",
    "status": "Available"
}

GET http://myserver:5555/orderapi/products

Invoking this will provide the following response:

{
    "products": [
        {
            "price": 100.5,
            "pid": "1",
            "productName": "toy",
            "status": "Available"
        },
        {
            "price": 50,
            "pid": "2",
            "productName": "stationary",
            "status": "Out of Stock"
        }
    ]
}

Resource First Approach

In this approach there are two variations:

  • Manually from scratch
  • Using existing services

Manually from scratch

Let us consider an example where you want to deliver an API for viewing and ordering products by using the existing backend systems. The URLs that you want to expose in the REST API are as follows:

http://myserver:5555/orderapi/product/{pid}
http://myserver:5555/orderapi/products
https://myserver:5555/orderapi/order

To achieve this, complete the following steps:

Step1: Document Type

Create IS document type product and order as below:

Product Order

Step2: Services

Create two IS services:

  1. getProductById: It takes pid as the input variable, fetches the product data from the backend and returns the data based on document type product.

  1. getAllProducts: It fetches all products and returns the product document list.

At this stage, test the newly created services by executing the services with various inputs.

Step3: REST v2 Resource

Create two REST v2 resources named ProductResource and OrderResource by selecting the option – “Empty REST Resource”.

  1. ProductResource

  1. OrderResource

Step4: REST API Descriptor

Create a REST API descriptor (RAD) named storeAPIDesc and add the REST v2 resources ProductResource and OrderResource.

The RAD General tab contains some default values, for example, host as the machine name along with the port, basePath as ‘/rad/<radName>’, scheme as ‘HTTP’. The Consumes and Produces default to ‘application/json’.

The REST Resources tab displays details of the REST v2 resources and each operation within it.

At this stage the Swagger is as follows:

The final URLs that a client would send are:

<schema>://<host>/<basePath>/<resource-paths>

So, based on the Swagger, there are three URL requests that can be made for the REST API.

  • http://SAG-GKLQMC2.eur.ad.sag:5555/rad/restAPISample:storeAPIDesc/products
  • http://SAG-GKLQMC2.eur.ad.sag:5555/rad/restAPISample:storeAPIDesc/product/{pid}
  • http://SAG-GKLQMC2.eur.ad.sag:5555/rad/restAPISample:storeAPIDesc/placeOrder

These URLs are different from the intended URLs:

  • http://myserver:5555/orderapi/product/{id}
  • http://myserver:5555/orderapi/products
  • https://myserver:5555/orderapi/placeOrder

You need to configure some more details in the RAD. The server here is “myserver” which is the production server and hence this is configured in the host field of the RAD as “myserver:5555”. Since the Swagger document contains all the information to invoke the REST API, the host value must be the production server before the Swagger is exposed to the client.

The basePath is changed from /rad/restAPISample:storeAPIDesc to /orderapi in the “Path” property of the RAD and the URL alias is automatically created.

After making the above changes to the RAD General tab as below:

The URL alias is created automatically as:

The Swagger document is changed as follows, which is the REST API that you wanted to expose:

The data exchange format can also be changed but for this REST API it is JSON as the consumes or produces is set to "application/json".

Now consider that, there is a need for another REST API to view only the products. So, you can create another RAD and add only the ProductResource. The URLs exposed now are:

  • http://SAG-GKLQMC2.eur.ad.sag:5555/rad/restAPISample:storeAPIDesc/products
  • http://SAG-GKLQMC2.eur.ad.sag:5555/rad/restAPISample:storeAPIDesc/product/{pid}

Change the basePath to “productapi” and change the consumes and produces to "application/xml" and then the URLs are changed as below which return the data in XML format.

  • http://myserver:5555/productapi/product/{id}
  • http://myserver:5555/productapi/products

So, what we see here is that you can create the REST v2 resources independently and then combine them in a RAD to create a REST API for different purposes.

Using Existing Services

If you already have existing doctypes and services and want to expose them as a REST API, then the above “Step1” and “Step2” are not required. You can directly start with creating a REST v2 resource, from “Step3” and then “Step4”.

Runtime Testing

View the Swagger document generated after creating the REST API descriptor by using the following URL:

schema>://<host><basePath>?swagger.json – This produces the Swagger in JSON format.

or

schema>://<host><basePath>?swagger.yaml - This produces the Swagger in YAML format.

For example, http://myserver:5555/orderapi?swagger.json

Based on this Swagger generate the URLs as defined in Runtime Testing section.

Limitations or Unsupported Functionality

When a Swagger document containing JSON schema specific constructs is imported, then the JSON schema constructs are lost since IS did not have support for JSON schema.

JSON schema support will be incorporated in REST API in future releases.

2 Likes