WebRFC – simply calling an RFC from javascript
Just a couple of days ago I found myself confronted with a little problem.
I was asked to update data in an SAP system from a web page.
Initially I found all sorts of approaches – writing a custom BSP, developing my own WebDynPro page, post the data into some database and import it from there later… But every single one of these approaches seemed way to complex for the task at hand.
But I did find one technology that seemed almost too simple: A WebRFC.
So what is it?
A WebRFC is an almost forgotten option to call a simple ABAP RFC through a simple URL, with URL encoded parameters.
Why simple ABAP RFC?
Due to the URL encoding you are a bit limited in passing table parameters and complex data types (just to be sure – you can deserialize in your RFC but lets not go there.)
Does it work with every RFC?
Well – there is a specific interface you have to implement. But you can always wrap the RFC you wrote a year back in a new WebRFC.
Now that we are throught the executive summary – I will walk you quickly through a sample on how you can use a WebRFC to generate some JSON which you can consume in your HTML5 application (hopefully you are using the SAPUI5 library).
Step 1: Create a regular function module
Open SE37, create a new function module (in this case I name it Z_SAMPLERFC) and assign it to a function group (in case you don’t have one handy – you can create them in SE80).
There is no need to define it as remote enabled.
Step 2: Implement the right interface.
In order to make an RFC that can be used as a WebRFC it hast to comply to a defined interface.
Specifically we need to provide a couple of fields which will be populated by the WebRFC handler or provide it with our output.
There are two different sections of the interface, the table parameters as well as changing paramters.
So lets address the table parameters first.
If your system informs you during the interface definition that table parameters are obsolete, just acknowledge it by pressing ENTER 😉
Open the tab called TABLES.
Here we need to define 3 different table parameters:
QUERY_STRING LIKE W3QUERY (QUERY_STRING is the name of the variable, LIKE is its typing and W3QUERY is its actual type)
This table will contain the content the key-value pairs passed as url parameters to the WebRFC. More on this later.
HTML LIKE W3HTML
This table will be filled with our output later by the called function module and returned to the client.
MIME LIKE W3MIME
If we where to return an image or any other binary data we can use the MEMI table as a vehicle to passt it back to the client.
Since we will be generating JSON later on we will not be using the MIME table but the HTML table.
Besides the actual payload going in and out of our RFC there is some meta-data that can be provided through the WebRFC interface. This happens using the a number of changing parameters.
They need to be defined on the “Changing” tab:
Specifically we need to define the CONTENT-TYPE for the http response by setting the CONTENT_TYPE field. We will set a default value for it, but it cold also be changed bynamically within the function module.
CONTENT_TYPE LIKE W3PARAM-CONT_TYPE DEFAULT ‘application/json’
For MIME data its length has to be provided in the CONTENT_LENGTH variable, but since we are using HTML as the output table we can just leave it empty after defining it:
CONTENT_LENGTH LIKE W3PARAM-CONT_LEN
The return code can be used to define whether the ITS session or the RFC connection are to remain open or get closed, after the call – the default value (0) which leaved the ITS session in place for later use, and terminate the RFC connection.
RETURN_CODE LIKE W3PARAM-RET_CODE
Step 3: Implementing some functionality behind the interface
As mentioned before WebRFC allows you to access your url parameters though the use of the QUERY_STRING table – which already breaks the parameters down for you as key-vlaue pairs.
In this first section of the code we get the value of a parameter called “_Name” into a variable called name.
DATA: name TYPE STRING.
SORT QUERY_STRING DESCENDING.
READ TABLE QUERY_STRING WITH KEY NAME = ‘_Name’.
name = QUERY_STRING-VALUE.
With the parameters available we can now do all sorts of ABAP magic … or for the sake of this post, just return it to the caller as a JSON array:
this second section of the code creates a new html document for us – again a table contrainign lines… and we fill it with a bit of JSON and write it into the table HTML which we created earlier.
So overall the code looks like this:
DATA: htmldoc LIKE LINE OF HTML.
CONCATENATE ‘{“results”: [ {“key”: “name”, “value”: “‘ name ‘”}, {“key”: “phone”, “value”: “911”}]}’ INTO htmldoc-line.
INSERT htmldoc INTO TABLE HTML.
The overall function should look very much like this:
FUNCTION Z_SAMPLERFC.
*”———————————————————————-
*”*”Local Interface:
*” TABLES
*” QUERY_STRING STRUCTURE W3QUERY
*” HTML STRUCTURE W3HTML
*” MIME STRUCTURE W3MIME
*” CHANGING
*” REFERENCE(CONTENT_TYPE) TYPE W3PARAM-CONT_TYPE DEFAULT
*” ‘application/json’
*” REFERENCE(CONTENT_LENGTH) TYPE W3PARAM-CONT_LEN
*” REFERENCE(RETURN_CODE) TYPE W3PARAM-RET_CODE
*”———————————————————————-
DATA: name TYPE STRING.
SORT QUERY_STRING DESCENDING.
READ TABLE QUERY_STRING WITH KEY NAME = ‘_Name’.
name = QUERY_STRING-VALUE.
DATA: htmldoc LIKE LINE OF HTML.
CONCATENATE ‘{“results”: [ {“key”: “name”, “value”: “‘ name ‘”}, {“key”: “phone”, “value”: “911”}]}’ INTO htmldoc-line.
INSERT htmldoc INTO TABLE HTML.
ENDFUNCTION.
As always don’t forget to Check, Save and Activate the RFC.
Step 4: Activate the RFC as a WebRFC
Once that is done… remember the name of the RFC and launch SMW0 the Web Repository
From the Internet Release Menu -> Function Module (F7)
Put in the name of your RFC
and hit the open padlock icon to make it available in public.
Step 5: Call the RFC
http(s)://<your system>:<your port>/sap/bc/webrfc?_FUNCTION=Z_SAMPLERFC&_Name=<your name>
And you receive beautiful JSON back.
Step 6: Mind all the stuff not mentioned here
Make it real – of course you can add exceptions, return values and error handling, as well as input validation to your RFC – but this should help you get started – SAP ERP generating JSON using an RFC called through HTTP.
If you need to configure security for this service you can configure the service in SICF.
How much simpler can it get.
Cheers!
Great Stuff - never heard about it.
br
Jürgen
Hi Sebastian,
Great Blog! I am not an abaper, it may be a basic question , appreciate your help on this.
at the moment the standard SAP structure W3HTML length is 255 chars .. how can we increase this length, becuase of this the JSON output is limited to 255 chars only not more than that .. .
Hi Ravi,
you can insert multiple lines into the table, in this way it is possible to cover way more than 255 chars.
Below a simple example, this could be extended by a loop + some caculation to do the insert in an automated way.
DATA:
string TYPE string,
htmldoc LIKE LINE OF HTML.
"string would contain i.e. 400 characters
"get first set of 255 characters
htmldoc-line = string+0(255).
INSERT htmldoc INTO TABLE HTML.
"get 2nd set of 255 characters
htmldoc-line = string+255.
INSERT htmldoc INTO TABLE HTML.
Hello Sebastian,
Is WebRFC supported by SAP?
Thanks
Hi Experts,
I need to call a WebRFC from SAP personas with a parameter (from a variable), I could able to frame the required URL using Javascript and save it in a variable. The problem is when using the variable for calling the WebRFC, the system considering the variable name instead of the value as the URL. How to overcome this?
Thanks in advance
Hi, here is an example:
http://myserver:1000/sap/bc/webrfc?sap-client=800&_FUNCTION=ZKEYSTORE&_KEY=EQ-{key}&_VALUE={value}
both key and value are filled using the copy value feature in SAP Screen Personas.
Hi,
I'm getting an issue while I enter this URL. Can you pls let me know what will come in the place of <you system> and <your port> in
http(s)://<your system>:<your port>/sap/bc/webrfc?_FUNCTION=Z_SAMPLERFC&_Name=<your name>
Thanks in Advance
Swetha
Hi,
e.g. your Personas URL lookgs like that:
http://personasserver.domainname:8000/sap/bc/bsp/persos/mainapp/index.html
and your RFC is called Z_SAMPLERFC, then your WEBRFC URL would look like that:
http://personasserver.domainname:8000/sap/bc/webrfc?_FUNCTION=Z_SAMPLERFC
Be aware that you need to change "personasserver.domainname" to your personas server, and the port 8000 to your port (it might not be 8000) to make it work.
Kind regards,
Christoph
Thanks for your reply Christoph.
But I don't have Personas installed in my SAP GUI. So does that mean I can't run this?
Thanks & Regards,
Swetha
Hi Swetha,
generally, you would not install Personas on SAP GUI, but on your application server ;-).
You can use a WEB RFC without having Personas on your application server installed.
Below some how-to papers about how to create a WEB RFC:
WebRFC Programming - SAP Library
SAP Screen Personas 3.0 and WebRFC&#39;s - SAP Imagineering - SCN Wiki
What I do not know is, how to authenticate in the WEB RFC, if it is called from an external application, that has no trusted relation with the application server. But perhaps someone else can shed some light on this topic.
Best regards,
Christoph
Hi Christoph,
I get it thanks.
I got the application server name and port. But still I get page cannot be displayed or could not find <server name> when I enter that URL.
Thanks & Regards,
Swetha
Perhaps the ICF node "sap/bc/webrfc" ist not active? You can check that in transaction SICF.
Best regards,
Christoph
Thanks for the wonderful info. Just a couple of comments -
1. Can we not use the POST method instead of the query string based method to pass parameters or GET method to pass HTML form data via JavaScript in Step 5
2. Also, I suppose if more complex data needs to be sent across, one would always wrap the function in a Web Service.
Cheers,
Ash
Hi,
I am not aware of a POST solution - if you find one let me know.
This is meant to be a super simple solution - if you need to do something more advanced make sure you use some of the more advanced options - ODATA with the Gateway, and SOAP Webservices are the first to come to mind.
Thanks for making us walk through new concepts.....
Super helpful! Thanks for your guidance!
Do you need to know ABAP to use WEB RFC? I might be using it for Personas.
A Web RFC is an ABAP program that runs on the server, and is exposed through a URL. So yes, ABAP is a requirement. To use an existing WebRFC from within SAP Screen Personas no ABAP skills are required.
Cheers,
--
Sebastian Steinhauer
SAP Screen Personas
Product Owner
Excellent concept! Thanks for sharing!!
New concept, thanks for sharing 🙂
Awesome stuff. For someone new to Personas like me, this is very very helpful. Thanks again.
Nice stuff, works fine and returns json data on the page. However, I need to use the JSON data returned in javascript. So I am using ajax request to getJSON from the url generated by the webrfc, but it gives me CORS header 'Access-Control-Allow-Origin' missing error. How can I configure the service to allow CORS.
Regards
Great Work.
Hi Sebastian,
While I am using the WBRFC link its asking for SAP Login IDÂ and password. Could you please let us know how to skip login credentials. Do we need to maintain any settings to avoid this as like we maintain WEBGUI = 1 in SE80 for ITS on T-Code based?
We are still using 4.6C version in our project.
Regards
Subhaskar