Skip to Content
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.

/wp-content/uploads/2011/11/get_tasks_sdn_85391.png

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:

/wp-content/uploads/2011/11/get_task_sdn_85392.jpg

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:

/wp-content/uploads/2011/11/claim_task_sdn_85393.png

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: 

/wp-content/uploads/2011/11/complete_schema_sdn_85394.png

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.

/wp-content/uploads/2011/11/complete_task_sdn_85395.jpg

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:

/wp-content/uploads/2011/11/processstartevent_sdn_85396.jpg

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 ๐Ÿ˜‰

To report this post you need to login first.

12 Comments

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

  1. Former Member

    Dear Stefan,

    Thank you for the explanation of the different operations that are available in the BPEM RESTful services.

    I have the following scenario:

    A leave requester sends creates a leave request. Now the approver has to check the leave request and has to either approve or reject. For this, the Mobile UI that we are creating should be able to show the approver with the leave details like the startDate, endDate and the requestNote.

    Now to get the details that are provided as input by the requester, which RESTful service shall I have to use?

    I tried using the ‘/bpm/bpemservices/taskinstances/<taskInstanceID>/details’ request and with the ‘Accept’ header value as ‘application/xml’, and I am only getting the details of the task like TASKNAME, POTENTIAL OWNERS, PRIORITY, PRESENTATION_NAME, PRESENTATION_SUBJECT, etc. But is there any way for us to get the details of the task like the startDate, endDate and the requestNote provided by the requester while applying for the leave?

    Any help would be greatly appreciated.

    Thanks and Regards,

    Santosh Giri

    (0) 
    1. Stefan Henke Post author

      Hi Santosh,

      Sure, this is also possible. You have to access the input data of the task via the url:

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

      This will return a xml or json document which you have to parse on your own. This is quite similar to what you have to do with the output data for completing a task (which is described in the blog).

      Best regards,

      Stefan

      (0) 
    1. Stefan Henke Post author

      Hi Venkat.

      you can check the Log Viewer in NWA to get the exception stacktrace. There it should be mentioned what is wrong with your DataObject. From your json snippet I can only see that you the schema on top refers to the Task Input whereas the DataObject on the bottom refers to the Task Output.

      Best regards,

      Stefan

      (0) 
  2. Former Member

    Thanks Stefan,

    I closely followed your blog again, i used the output schema instead of input schema to pass the data object, I don’t get an error on the log viewer.

    also i tried to use the example of leave request componet provided and to check if i get the same issue.

    If you can let me know the mistake of json snippet will be a great help.

    {

        “ns2.DataObject”: {

        “@type”: “http://ciber.nl/leavereq/wdp_ui/EnterLeaveComponent/ports#EnterLeaveCompleteEventTypeOUTPUT“,

        “ns2.containment”: {

        “@name”: “EnterLeaveCompleteEvent”,

        “@type”: “http://ciber.nl/leavereq/wdp_ui/EnterLeaveComponent#Context“,

        “ns2.containment”: {

        “@name”: “DO_LeaveRequest”,

        “@type”: “http://ciber.nl/leavereq/wdp_ui/EnterLeaveComponent#Context_DO_LeaveRequest“,

        “ns2.property”: [

         {

        “ns2.name”: “DateTo”,

        “ns2.value”: “2012-04-19”

        },

        {

        “ns2.name”: “Type”,

        “ns2.value”: “Sick”

        },

        {

        “ns2.name”: “DateFrom”,

        “ns2.value”: “2012-04-18”

        },

        {

        “ns2.name”: “Approved”,

        “ns2.value”: “true”

        },

        {

        “ns2.name”: “Reason”,

        “ns2.value”: “test”

        }

        ]

        }

        }

        }

        }

    if remove the data and only pass

    {

        “ns2.DataObject”: {

    }}

    it executes successfully and task is completed, i’m only facing the problem with Context  name and value pair.

    and the response i get is

    XML Parsing Error: no element found

    Location: data:text/xml,

    Line Number 1, Column 1:

    1. Status Code: 400 Bad Request
    2. Server: SAP NetWeaver Application Server 7.20 / AS Java 7.30
    3. Content-Type: text/xml
    4. Date: Wed, 18 Apr 2012 22:02:13 GMT
    5. Content-Length: 0
    (0) 
    1. Stefan Henke Post author

      Hi Venkat,

      if you pass an empty DataObject this is working due to the fact that the server is resolving the right DataObject and passing an empty instance for task completion. However, if you use output mapping in your task, this will result in a non-functional process flow.

      Can you try to use an escape character in the namespace of the DataObject:

      http://example.org/hello_world => http:\/\/example.org\/hello_world

      This might solve your problem.

      Best regards,

      Stefan

      (0) 
      1. Former Member

        Stefan,

        I could solve the problem by passing the output schema as xml replaced by the types with values and the only difference is that we need to take off the xml notation,

        <?xm version=”1.0″ encoding=”UTF-8″ standalone=”yes”?> in the beginning of the request body from the xml output schema.

        Thanks for all your help and i will reach out to you in case i see any problems.

        Thanks,

        Venkat.

        (0) 
  3. Former Member

    HI Stefan,

    The blog is really useful. I want to use the JSON response in my application instaed of XML.

    I just wanna have a look at the structure of the JSON response for “get All task by status/priority”. Please give me link or some snapshot for the same.

    Thanks,

    Indira

    PS:I got a link which gives JSON response structure for ‘get all task for a user’. Is this relevant to your blog or not. (i wanted to confirm).

    (0) 
  4. Former Member

    Hi Stefan,

    currently I am trying to build an own little uwl and to run it on an mobile device. I started to search for some tutorials with this topic and I found your blog. Now I wanted to try your RESTful Service to access the Process-Data and to build my own UI. But unfortunately Code Exchange is offline. Is there a possibility to still get access to your project files?
    And am I right, that I first have to deploy your service to the AS where my process is running to work with it. For me it is not clear if such services are already implemented with NetWeaver 7.3 BPM? Sorry for the stupid question, but I am still very unexperienced in this topic.

    I would appreciate an answer from you.
    Sincerely Dominik

    (0) 
    1. Stefan Henke Post author

      Hi Dominik,

      Code Exchange has been shut down unfortunately. So, there is currently no way to get the respective coding of the RESTful Service. However, the latest SP of NetWeaver BPM 7.3 EhP1 comes with an OData service that supports task retrieval:

      http://scn.sap.com/community/bpm/blog/2013/10/10/custom-uis-with-the-bpm-odata-service

      I would recommend you to take a look into this if possible. Among others you will get official support by SAP.

      Best regards,
      Stefan

      (0) 
      1. Former Member

        Hi Stefan,

        thx a lot for the answer! This sounds very interesting and I hope I can get my administrator to patch the AS as soon as possible! ๐Ÿ™‚

        Regards
        Dominik

        (0) 

Leave a Reply