This blog is part of a collection of blog entries that shows architectural concepts and configuration of the SAP PI REST Adapter. We also added some sample scenarios to make it easier for you to understand how your scenario can be implemented using the PI REST Adapter.

A complete list of all blog entries can be accessed from here PI REST Adapter – Blog Overview.

Intro

If you get in touch with the REST Adapter for the first time, configuration and concept might not be obvious to you.

With this Blog I want to guide you through the internal processing and the configuration capabilities of the REST Adapter.

At a first glance

REST itself does not represent a strict protocol, but rather an architectural approach for implementing Web Services in a simple fashion using HTTP calls and JSON or XML as payload.

The advantage of REST API’s is that by using HTTP as transport layer it is based on existing infrastructure and by using JSON (or XML) as content format, the payload can be easily consumed by browsers or other backend systems.

The downside of that flexible approach is that not every REST service is necessarily implemented the same way as others.

That requires that any REST client has to be either exactly tailored to the API it is consuming or has to be flexible in a way that it can be customized to consume REST API’s. THE SAP REST Adapter follows the latter approach which is also the reason why you find so many configuration options on the REST Adapter configuration UI. The adapter is kind of a Swiss Army knife for REST services. If you do not understand the adapter configuration UI at a first glance, please don’t be afraid and do not panic. Your reaction is quite normal.


From REST to XI and back

What the REST Adapter mainly does is to allow mapping information between HTTP calls and XI messages.

HTTP_to_XI.pngFor HTTP calls the adapter can access information from the URL and the URL parameters, from the HTTP operation (GET, POST, PUT, DELETE), from the HTTP Header (e.g. cookie or encoding information) and the payload itself. On XI Messages the adapter can access information from the XI message header and payload.


From HTTP Call to XI Message

When converting a HTTP call into a XI Message, selected information, except the payload, are taken from the HTTP call and written into XI Header variables.

For convenience, the REST adapter defines a predefined set of XI Header variables like (url, service, resource, id, operation, etc.) that can be filled with information from a HTTP call for later use in the Integration Flow or diagnostic purposes.

The payload can be taken as it is, converted into UTF-8 code page and can be converted from JSON into XML and vice versa.

For XI Messages that expect XML and are bound to an interface / operation, the adapter can enclose the payload XML with a given or calculated interface / operation name, based on the incoming HTTP call information.


From XI Message to HTTP Call

On receiver side, the REST Adapter generates dynamically an HTTP URL from information provided in the configuration and from XI Header and XI Payload. Based on given rules the interface / operation name can be used to determine the HTTP operation to use (POST, PUT, GET and DELETE). The payload can be converted to format (XML, JSON) and a code page that the REST service is expecting.

Let’s have a look what is happening behind the scenes.

Behind the scenes

In the following I am going to give you a detailed overview about how the REST adapter works for sender and receiver channels, what the single processing steps are and how these steps can be configured.

I am ignoring features and settings that are common for adapters (HTTP security, timeout, QoS, etc. )

Inbound REST Services – servicing REST APIs

Using the REST Adapter you can create an Integration Flow with a REST API on sender side. The adapter would then convert incoming HTTP calls into XI messages and vice versa (for synchronous scenarios).

The REST Adapter allows dynamic dispatching of an incoming HTTP call to a sender channel, by using the URL, the HTTP operation or parts of the content as selection criteria.

In general REST Adapter is processing requests under the following URL root:

http:<myHost>:<myPort>/RESTAdapter/

The following graphic shows the single processing steps of an incoming HTTP call.
/wp-content/uploads/2014/12/image004_611060.png

Step 1: Find channel from URL, Payload and HTTP Operation


The Fixed URL Part

In most cases you want to bind the fixed part of your REST URL to a specific PI channel.

You have to set up the channel endpoint name, so that it looks like

http:<myHost>:<myPort>/RESTAdapter/API/V2.0/Customer


The Dynamic URL Part

If you want to serve just a single REST API, the dynamic part is rather static like

http:<myHost>:<myPort>/RESTAdapter/API/V2.0/Customer_Create


If you want more than one REST URL to be bound to a single channel, you can use URL patterns like

…/RESTAdapter/API/V2.0/{resource}/{id}?operation={opname}

This URL pattern would serve

…/RESTAdapter/API/V2.0/customer/123?operation=create

as well as

…/RESTAdapter/API/V2.0/order/222?operation=delete

But it would not match

…/RESTAdapter/API/V2.0/order?operation=create

Since the {id} part is missing in the URL.


Content based channel filter

The fixed endpoint name does not have to be unique between PI channels. For channel selection the adapter also uses the dynamic part of the URL as well as a simple filter based on the payload content. You can limit the channel only to process incoming messages with a specific value in a JSON object or XML tag.

Having this dynamic channel selection feature, you can hide complex message processing landscapes behind a few APIs.


HTTP Operation based filter

You can also use the HTTP operation (get, put, post, delete) as a selection criteria for a channel. That allows you for example to set up two Integration Flows with the same URL, but one used for insert operations (POST) and the other used for updates (PUT).

Result of this step is that the Adapter found a matching channel for further processing of the message. If no channel was found, an HTTP error will be returned.


Step 2: Payload conversion

REST services usually use JSON as payload format, while PI used to work on XML documents, therefore the adapter allows converting an incoming JSON payload into XML. For synchronous calls the result message can also be converted on its way back.

It is also possible here to specify the charset of the payload.

Since the adapter allows using data of the payload for dynamic configuration, the payload conversion is done at an early stage.


Step 3: Extracting information from URL, Header and Payload

In this step the information of the various parts of the incoming HTTP are processed and stored in custom or predefined variables. The placeholders in the URL pattern allow specifying dynamic parts of the URL. In addition the adapter allows in this step to map information from the HTTP call to predefined or custom variables for later use in the integration flow. These variables are stored in the XI message header.


Step 4: REST operation detection

A REST call has a predefined operation semantic that is usually bound to the HTTP operation, like

GET for fetching data,

POST for creating an object,

PUT for updating an object and

DELETE for deleting an object


For example a HTTP DELETE on http://myhost:myport/customer/99 is a common URL pattern that in this case allows deleting the object customer with id 99. But the logical REST operation can also be encoded in the URL or an URL parameter and does override the HTTP operation, so the REST operation is part of the URL. Such REST API could look like this


HTTP POST on http://myhost:myport/customer/99?operation=remove

In this step, the REST adapter sets the logical REST operation, based on the user configuration.

After this step we have mapped all necessary information from the incoming call to the new XI message.


Step 5: Mapping to PI interface / operation

XI channels are usually bound to an interface or operation and XI expects in such cases that the payload is in XML format and that the outermost element contains the interface / operation name.

Assume that the incoming payload is not PI aware and in JSON format. The adapter would then convert the JSON to XML and in this step add the missing interface / operation name.

Since the channel allows processing multiple REST URLs, the user has to configure rules for adding the correct outer XML element, based on the information of the incoming call. The rules can make use of the predefined or custom variables and do allow a simple pattern matching type, called Glob.


Text pattern matching using Globs

If you want to match a group of values and not only an exact value, you use a Glob expression. The rest adapter supports two wildcard characters.

Wildcard character

Description

Example

?

Match exactly one unknown character

?at matches Cat, cat, Bat or bat, but not at

*

Match any number of unknown characters (regardless of the position where it appears, including at the start and/or multiple times)

*Law* matches Law, GrokLaw, or Lawyer


Step 6: Sending message to PI

In this final step the message is sent from the REST Adapter to the PI message system.


Optional: Processing the result message

For synchronous calls with result message, the returning XI message is converted back into the desired format and code page and returned as the result of the incoming HTTP call with a HTTP status of 200.


Optional: Custom Error Handling

Custom Error Handling is an optional feature that allows to ignore or to create error conditions.

On sender side this feature can be triggered by any error (Exception) within the adapter, like JSON/XML conversion error, configuration error, etc.

In addition the feature can be triggered by the content of a result message in synchronous call scenarios (JSON object value, XML element value, Text). When checking the value, text Globs can be used.

The behavior of the feature after being triggered can be customized by the chosen strategy. This can be one of

“Error” – Log an error and treat message delivery as NOT successful

“Ignore Error” – Log the error and treat message delivery as successful

“Custom Result” – Set the message delivery as successful and returns a custom HTTP status code and message payload

Outbound REST Services – calling remote REST APIs

Using the REST Adapter you can call other REST services as part of you Integration Flow. The adapter converts outgoing XI messages into HTTP calls and in synchronous scenarios sends back the HTTP result as XI message.

Note: Concepts that I already explained in the “Inbound REST Services” section are not covered again in this section in detail.

The following graphic shows the single processing steps of an outgoing HTTP call.


Step 1: Read XI Message

In the first step, the outgoing message is taken from the PI messaging system and payload as well as the dynamic header variables is extracted for further processing.


Step 2: Operation Rules

If the incoming payload is XML the adapter extracts the interface / operation name from the outermost XML element. You can add own rules defining how to map the interface / operation along with its namespace name to dynamic variables.

Let’s have a look how two example interface / operations can be mapped so that the REST resource and the REST operation can be extracted.

Operation

Namespace

Variable

Value

Customer*

http://sap.com/xi/XI/Demo/

resource

customer

Order*

http://sap.com/xi/XI/Demo/

resource

order

*Delete

http://sap.com/xi/XI/Demo/

operation

DELETE

*Create

http://sap.com/xi/XI/Demo/

operation

POST

Using the rules above, the adapter could map interface / operations like “CustomerCreate”, “CustomerDelete”, “OrderCreate” and “OrderDelete” to custom internal variables that can be used for dynamic URL generation.

The example above is using text Globs in order to show the flexible configuration that is possible. You can also use fixed settings like

Operation

Namespace

Variable

Value

CustomerCreate

http://sap.com/xi/XI/Demo/

resource

customer

CustomerCreate

http://sap.com/xi/XI/Demo/

operation

POST


Step 3: Generating Dynamic URL

The URL to be called can either be a static URL or a dynamically generated URL by using placeholder variable values that have been set up during the previous steps.

For dynamically generated URL’s you have to specify the dynamic parts of the URL with placeholder variables in curly brackets (similar to sender channel configuration), so that it looks like

http://www.google.com/finance/info?q={stock_symbol}

The custom placeholder variable “stock_symbol” has now to be bound to the source where the value is coming from. Types of sources are

“Manual Value”: just provide a manual value yourself

“Adapter Specific Attribute”: refer to an XI Header variable

“XPath”: reference an XML element from the incoming XML payload

“JSON Expression”: reference a JSON object

“Binding”: specify a value from the channel interface binding

For each incoming message a new URL will be generated.


Step 4: Determining the HTTP operation

Similar to the previous step, the HTTP operation to be used for the HTTP call can be either static and manually set up or can be calculated based on the incoming XI message.

If the HTTP operation has to be determined dynamically you specify the source of the value to be used as selection criteria and provide a matching value or GLOB expression for each of the four HTTP operations. The source types are the same is in previous step when generating the URL.

For rare cases when you need more than one rule per HTTP operation, the UI provides a table where you can add more rules.


Step 5: Setting up the HTTP Header

If the REST service requires certain HTTP Header values, these can be setup as manual values or can reference dynamic variables set up in the previous steps.


Step 6: Converting Payload

In case the XI message is in XML format and does contain the interface / operation as the outermost element and this element is not expected by the REST service you are calling, you can set up the adapter to strip it off.

If the payload from the XI message system does not match the target format you can again add code page and format conversion is this step.


Step 7: Calling REST Service

Last step is then to call the remote REST service. Depending on the returned HTTP status code the processing is then successful or not.


Optional: Result message processing and Response Determination

In case of a synchronous scenario, the result message returned from the HTTP server will be sent back to the PI messaging system.

This step also contains optional code page and format conversions.

If the channel is bound to an interface / operation, the result has to be in XML format and has to contain the response interface / operation as the outermost element. This is done automatically by the adapter. You just have to specify rules in order to determine which interface / operation to be used.

The configuration is similar to the operation rules, but instead of setting variable and value, you can set response interface / operation and namespace.


Optional: Custom Error Handling

Similar to the sender channel, the receiver allows setting up custom handling of error conditions.

This feature can be triggered by any kind of error in the receiver adapter (errors during conversion, configuration, invalid URL, etc.) or based on the HTTP result (status code, status text, payload content).

If a rule that you specify on this information is triggered, you can force an error condition, you can ignore the error or create a custom result message that, if in synchronous scenario, then will be sent back to the PI messaging system.

Let me explain why this feature is necessary especially on REST receiver channels.

Imagine you want to call a remote server in order to delete a customer with a certain ID and the URL is dynamically created by the adapter. The remote REST URL could look like this

http://server:port/API/Customer/222?op=delete

If the HTTP server returns a HTTP code of 404 (not found) the adapter cannot decide whether the URL is incorrect or whether the customer with ID 222 just does not exist.

The semantic of the HTTP result is dependent on the implementation of the specific REST API and so it needs to be configurable.

Hopefully helpful hints

  • You can use text Globs (* and ?) on every field, where you check for a certain value
  • Payloads that are to be converted are logged to the message monitor before and after conversion
  • Make sure that fields in which you specify a custom request or result, must not contain line breaks
  • Use the predefined dynamic variables for debugging. Even if you do not need the dynamic variables in the Integration Flow, you can use them for tracing values, since the variables are shown in the log with the message header
  • For testing your sender channel selection and set up, just open a browser and call the URL of the sender channel. You will see which channels do match the URL. The first one, from the top, that matches the URL will be the one to process the message
  • If you need a REST client for testing, try Googles Chrome App Postman

Finally

If you were brave and made it through all the previous sections without cheating and scrolling forward, you should have a quite good understanding of the PI REST adapter by now.

I hope I could clarify architecture and configuration options, so that you now are ready and get your hands dirty by setting up your own REST scenarios with the PI REST adapter. For a more “hands on” experience, please check out the other REST Scenario Blog pages PI REST Adapter – Blog Overview.

Don’t be afraid, it doesn’t bite.

To report this post you need to login first.

8 Comments

You must be Logged on to comment or reply to a post.

  1. Matthias Heiler

    Hello Ivo,

    thanks a lot for this wonderful introduction into the REST Adapter.

    I have one remark: usually when we talk about sender/receivers in PI we regard it from the perspective of the application. (for those of you who know the old XI it was from the perspective of the PI).

    So if a sending application send a message to PI to process it we talk about a sender interface or sender channel. From the perspective of PI it is of course a receiving message (PI receives a message from a sender). And a receiving channel in PI is a channel that sends a message out to a receiver application, so from the perspective of the application it is a receiver interface or receiver channel, but from the perspective of PI it is a sending functionality.

    If I read your document I understand it the other way around. So if you talk about the Inbound REST Service you look at it from the perspective of PI (not from the application). This makes it a little bit hard to understand which direction Inbound or Outbound has.

    (0) 
  2. ceren çetin

    Hi ,

    I wanna handle 400 status code from hybris response.You said that it can be possible in rest receiver adapter with defining operation rules but there is no any sample anywhere. Pls write a sample how to define custome error handling related with response status code 400?

    In PI I could not handle a message has 400 status bad_request . But I want to handle it.

    (0) 
    1. Ivo Kulms Post author

      Hi Ceren,

      you are right. My mistake. I just realized that the Custom Errorhandling I described will be shipped with SP15 which is in March 2015.

      Ivo

      (0) 
  3. Rick Ni

    Hi Experts,

    If we want to send JSON format data via HTTP POST, for example , XML convert JSON , the result will be :

    —JSON data———————————

    {

      “count”: “2”,

      “item”: [

        {

          “xx_product_id”: “201502AG110000189”

        },

        {

          “xx_product_id”: “201502AG110000190”

        }

      ]

    }

    ————–the result is ok by soapUI sent—————————————————————

    POST https://server/order/apply_supplier_hd HTTP/1.1

    Accept-Encoding: gzip,deflate

    Content-Type: application/x-www-form-urlencoded

    Content-Length: 251

    Host: server

    Connection: Keep-Alive

    User-Agent: Apache-HttpClient/4.1.1 (java 1.5)

    platform_id=XX000366&version=1.0.0&account=beta&password=barabara&data=%7B%22count%22%3A%222%22%2C%22item%22%3A%5B%7B%22xx_product_id%22%3A%22201502AG110000189%22%7D%2C%7B%22xx_product_id%22%3A%22201502AG110000190%22%7D%5D%7D

    ———————————————————————————————————————

    How can setting the pattern variable replacement , especially “&data={jsondata}” which using “JSON Expression”

    (0) 
  4. Alex Wiebe

    Probably an intro PI problem, but it seems I have a rogue sender channel. I am trouble shooting a simple demo to query bank details, and I get the following error response:

    <html><head><title>Error</title></head>
    <body><h1>Error</h1><pre>
    Multiple channels configured to handle "GET" request to "/demo/bank/1": REST_Sender, BankQueryRestful_Rest
    </pre></body></html>

    I can see in the Integration Builder the “BankQueryRestful_Rest” communication channel, but I cannot find the “REST_Sender” channel.

    How do I find this channel? is a default? (I get the same pattern of error on a different test I’m building – namely multiple channels configured, mine and this “REST_Sender”)

    (0) 
    1. Alex Wiebe

      Sorry – beginner’s error. Seems I had created a REST_Sender a while ago and deleted it. But not activated the delete to really delete it. It was visible in the Monitor and in the Change List, but not the Objects browser. sigh.

      (0) 

Leave a Reply