Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
stefan_henke
Contributor
Today, I want to give you the first hands-on picture of the RESTful service for NetWeaver BPM. If you don´t know about this project, then here’s a quick introduction: It is a RESTful service based on the APIs available in NetWeaver BPM 7.30. It is available on Code Exchange at [1]. For a more general introduction please see one of my other blogs at [2]. Later in this blog there will be several examples of HTTP requests that can be sent to the service in order to retrieve data from, or trigger operations in, the NetWeaver BPM system. As I want to keep this simple at the beginning, I´m not going to be using a programming language to access the service: I´m going to use an add-on for the Firefox browser to do the communication instead. This add-on is called “REST client” and can be downloaded from here:

https://addons.mozilla.org/de/firefox/addon/restclient/

The benefit of using such a client is that, on the one hand, most of the technical details of HTTP are implemented by the “REST client” add-on and are therefore hidden from you as a user. On the other hand, you have the complete freedom to specify the necessary HTTP parameters, such as the HTTP method or the HTTP header parameters.

Below I will provide all the settings in the UI of the “REST client” add-on in order to perform a certain request. The respective URLs are given only as relative URLs to save space in the tables. You have to adjust them to your needs by adding the server host and port (for example, http://localhost:50000) at the beginning. Adding the Request Header “Authorization” is mandatory for each HTTP request, as you always have to log on to the AS Java. If you do not do this, the BPM RESTful service will respond with an HTTP 401 error. The “REST client” allows you to set this Request Header using the “Login” button in the toolbar. To make things easier and to avoid unexpected issues, I recommend that you use a user with administrative access to BPM.

It is possible to replace the value “application/xml” by “application/json” in the examples if you prefer json for communication over XML. The last example in this blog shows this explicitly, so if you are having problems to switch from XML to json in one the examples, then you might like to take a look there.

Retrieve Task Assigned to User

The first example request will ask the BPM RESTful service for a list of Tasks assigned to a specific user. The user is determined from the Request Header “Authorization”. We will only query the status “READY” and “RESERVED”, but you may also try to modify the status to play around a bit.

Method

GET

URL (relative)

…/bpm/bpemservices/taskinstances?status=READY&status=RESERVED

Request Header

Authorization

<According to your settings>

Accept

application/xml

Request Body

None

In the following screenshot you can see how to configure the “REST client” for this request. The structure of the HTTP Response might be of particular interest to you.

To get a meaningful result, make sure that the user you are using is either the ‘Potential’ or ‘Actual’ owner of an active task. You can verify this in the UWL or the NWA.

Retrieve a Specific Task and Its Details

If you are interested in a single task that you know the ID of, you can also get its data directly without retrieving all assigned tasks.

Method

GET

URL (relative)

…/bpm/bpemservices/taskinstances/<taskinstanceid>

Request Header

Authorization

<According to your settings>

Accept

application/xml

Request Body

None

Rather than entering the request data again, you can also use the navigation capabilities that the “REST client” provides. If you have already executed the previous request, you can simply use the generated link of a task from the HTTP response.

From the document provided by the server for your request, you can see that it does not contain all of the information about the task. This resource is meant to provide only the most important information that can be displayed in a task list. You can access the Task Details to view the complete task data.

Method

GET

URL (relative)

…/bpm/bpemservices/taskinstances/<taskinstanceid>/detail

Request Header

Authorization

<According to your settings>

Accept

application/xml

Request Body

None

Below you can find another screenshot of the “REST client” showing the request to get the Task Details:

So far, we have only used the BPM RESTful service to retrieve data in XML or json format which is usually consumed by another application for integration purposes. However, the service was not exclusively designed for this. Try to send the following request (be aware that the “Accept” header value has changed).

Method

GET

URL (relative)

…/bpm/bpemservices/taskinstances/<taskinstanceid>/detail

Request Header

Authorization

<According to your settings>

Accept

text/html

Request Body

None

You will now get an HTML document as the service forwarded your request to the BPM Task UI. This will become more visible if you open the URL in your Firefox Web browser. This illustrates one of the major advantages of REST over SOAP-based Web services: One access point and one component for different clients and scenarios.

Claim a Task

With this example, it is the first time that we do not use the method “GET” to simply read data. Rather, we will use the “PUT” method to tell the server that we want to modify data. Specifically, we want to “claim” a task which means we want to make ourselves the actual owner of the task. You might wonder why the “Accept” Header needs to be set. This is because the server knows what kind of client you are.

Method

PUT

URL (relative)

…/bpm/bpemservices/taskinstances/<taskinstanceid>?operation=CLAIM

Request Header

Authorization

<According to your settings>

Accept

application/xml

Request Body

None

Again, you can find a screenshot of how to configure “REST client” for this request here:

This time the server is responding with HTTP status 204 telling you that the HTTP response is actually empty. So, if you access the BPM RESTful service, you should be aware of this and not rely on status 200 only.

Complete a Task

So far, we haven´t used the Request Body to send data to the BPM RESTful service as part of our requests. When changing a task status to ‘Completed’, we have to provide data that is used for the output of the task. The BPM runtime will use this output data to map it to the process context. The output data follows a certain schema (that is, it is a hierarchical structure of data attributes). However, the concrete attribute structure and their semantics is individual to each task and can be modeled in the Process Composer. Therefore, the following request cannot be reused one by one for your specific tasks.

First of all, we ask the server for a definition of the schema that the Task Output offers. This can be done using the dedicated HTTP resource for this purpose.

Method

GET

URL (relative)

…/bpm/bpemservices/taskinstances/<taskinstanceid>/output?schema=true

Request Header

Authorization

<According to your settings>

Accept

application/xml

Request Body

None

As you can see from the HTTP response in the following screenshot, we have retrieved the structure that the server is expecting in a request to complete the task: 

We now have to create an XML snippet that matches this schema in order to trigger the request to complete a task. It is basically about replacing the <type> tags by <value> tags.

Method

PUT

URL (relative)

…/bpm/bpemservices/taskinstances/<taskinstanceid>

Request Header

Authorization

<According to your settings>

Content-type

application/xml

Accept

application/xml

Request Body

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<DataObject xmlns="http://sap.com/bpm/rest" type= "http://sap.com/tc/bpem/content/predefs/wdui/CompleteCancel/ports#CompleteTypeOUTPUT">

<containment name="Complete" type="http://sap.com/tc/bpem/content/predefs/wdui/CompleteCancel#Context">

<property><name>description</name><value>My Description</value></property>

<property><name>subject</name><value>My Subject</value></property>

</containment>

</DataObject>

As you can see from the following screenshot, the Request Body is now filled. It is mandatory in such cases to set the HTTP Header ‘content-type’ to let the server know which data format the Request Body contains.

The server again responds with an HTTP status 204, as the Response Body does not contain any data. Be aware that it is only possible to call this action once. If the task has moved to status ‘Completed’, another complete action will return an HTTP error code 500.

Start a New Process Instance

With the last example, I want to demonstrate how you can start a new Process Instance using the BPM RESTful service. Technically, it is very similar to the ‘Complete Task’ example: You have to place a PUT request to the server and provide data within the Request Body. To include some new features in this example, I will perform the request using json as the data format. Semantically, there is no difference between the XML and the json data format used.

First of all, we have to find the right Process Definition. Getting the right Process Definition is quite easy if you know its name as well as the Development Component it is in. Just send the following request:

Method

GET

URL (relative)

…/bpm/bpemservices/processdefinitions?vendor=<vendor>&dcName=<dcName>&processName=<processName>

Request Header

Authorization

<According to your settings>

Content-type

application/json

Request Body

None

From the returned data, you can easily extract the ID of the Process Definition and use it in the upcoming request. In order to start a new Process Instance, we now have to get the service which we have to call in order to start the Instance. This is known as Process Start Event.

Method

GET

URL (relative)

…/bpm/bpemservices/processstartevents?processDefinitionId=<processDefId>

Request Header

Authorization

<According to your settings>

Content-type

application/json

Request Body

None

Having identified the right Process Start Event, we have to know which data we have to provide as part of the request to trigger this event. We can retrieve a schema of this data by accessing the Process Start Event resource using a GET request:

Method

GET

URL (relative)

…/bpm/bpemservices/processstartevents/<processstarteventid>

Request Header

Authorization

<According to your settings>

Content-type

application/json

Request Body

None

From the following screenshot you can see that the server will respond with a json snippet that describes the data we have to pass to the start event:

Now we know everything we need to start a new Process Instance by sending a final request to the server.

Method

POST

URL (relative)

…/bpm/bpemservices/processstartevents/<processstarteventid>

Request Header

Authorization

<According to your settings>

Content-type

application/json

Accept

application/json

Request Body

{"ns2.DataObject":{"@type":"http:\/\/www.example.org\/Test\/#+ComplexOperation","ns2.property":[{"ns2.name":"string","ns2.value":"myValue"},{"ns2.name":"boolean","ns2.value":"true"},{"ns2.name":"integer","ns2.value":"4"}]}}

If you send this request to the server, it will create a new instance of the Process Definition and direct its data, mainly the Process Instance ID, as part of the Response Body.

Conclusion

In this blog, I have demonstrated how to access the RESTful service for NetWeaver BPM in style of a tutorial. You should now have a better understanding of how things work. In a real world use case, you definitely wouldn´t use a client like the Firefox add-on used here to access the service, but implement the client in a programming language. However, for demo purposes it is the most intuitive way to get familiar with the topic. As the examples cover the specific settings for HTTP, it should be not much of a problem for you to implement these requests in a programming language of your choice.

Have fun with it 😉

12 Comments