Skip to Content

JSON Adapter for ABAP Function Modules

JSON Adapter for ABAP Function Modules

This blog explains how to use an ABAP class that allows calling function modules with a URL and a JSON representation of ABAP data.

The code to this project is available in this GitHub repository: cesar-sap/abap_fm_json · GitHub.

If you have problems installing it via SAPLink or abapGit, try the ABAP transport files here: abap_fm_json/transport/ at master · cesar-sap/abap_fm_json · GitHub.


ABAP Function Modules is one of the best and most useful features of the ABAP application server. They provide encapsulation of functionality in an easy to use package. They are the basis of ABAP ability to interoperate with the external world, thanks to, mostly, two built-in features: the RFC library (where the F comes from “Function”) and the SOAP adaptor, that allows SOAP compliant Web Services to be built from function modules.

ABAP Function Modules are also great for one more thing: they provide a name based parameter interface. This is something not new to ABAP developers, but this allows an incredible flexible way of parameter passing, including references, complex nested structures and tables. Shortly, with ABAP Function Modules you have the full power of the business suite at your service.

But, the RFC, while great, is a binary only library that could be cumbersome to use, and it is not available for all platforms. The SOAP adapter, while good for SOA enabled sites, could be also more complex that necessary and may have an overhead that makes it a non-option for some use cases, like, for example, data ready for consumption from user interfaces.

Just imagine how great could be to call a function module with a URL:


and get the results of the function module call in JSON format:






          RFCPROTO: “011”,

          RFCCHARTYP: “4103”,

          RFCINTTYP: “LIT”,

          RFCFLOTYP: “IE3”,

          RFCDEST: “seppuku_NXK_00”,

          RFCHOST: “seppuku”,

          RFCSYSID: “NXK”,

          RFCDATABS: “NXK”,

          RFCDBHOST: “seppuku”,

          RFCDBSYS: “ADABAS D”,

          RFCSAPRL: “731”,

          RFCMACH: ” 390″,

          RFCOPSYS: “Linux”,

          RFCTZONE: ” 3600″,

          RFCDAYST: “”,

          RFCIPADDR: “”,

          RFCKERNRL: “721”,

          RFCHOST2: “seppuku”,

          RFCSI_RESV: “”,

          RFCIPV6ADDR: “”



Furthermore, imagine that the function module has input parameters, and we can pass them as part of the query string:


And get the details of the flight:



          FLIGHTTIME: 65,

          DISTANCE: “555.0000”,

          UNIT: “KM”,

          UNIT_ISO: “KMT”,

          PLANETYPE: “DC-10-10”,

          FLIGHTTYPE: “”



          ECONOMAX: 380,

          ECONOFREE: 0,

          BUSINMAX: 41,

          BUSINFREE: 0,

          FIRSTMAX: 18,

          FIRSTFREE: 0



          AIRLINEID: “LH”,

          AIRLINE: “Lufthansa”,

          CONNECTID: “2402”,

          FLIGHTDATE: “2013-01-28”,

          AIRPORTFR: “FRA”,


          AIRPORTTO: “SXF”,

          CITYTO: “BERLIN”,

          DEPTIME: “10:30:00”,

          ARRTIME: “11:35:00”,

          ARRDATE: “2013-01-28”,

          PRICE: “242.0000”,

          CURR: “EUR”,

          CURR_ISO: “EUR”


    EXTENSION_IN: [ ],




              TYPE: “S”,

              ID: “BC_IBF”,

              NUMBER: “000”,

              MESSAGE: “Method was executed successfully”,

              LOG_NO: “”,

              LOG_MSG_NO: “000000”,

              MESSAGE_V1: “”,

              MESSAGE_V2: “”,

              MESSAGE_V3: “”,

              MESSAGE_V4: “”,

              PARAMETER: “”,

              ROW: 0,

              FIELD: “”,

              SYSTEM: “NXK001”




Isn’t it great?

And then, imagine that you have to pass some ABAP structure or table to the function module. You could just go and write it in JSON and pass it to the function module in the payload of a POST request:


This will be the response, showing that a new booking has been created:


Output formats

JSON (the JavaScript Object Notation) is the basis for this class. The default output format is JSON and the only supported input format (apart form the query string params) is JSON. But, other possible output formats have been implemented.

JSON has been seeing an enormous increasing in its use in the last years, especially for its high suitability at being used directly in JavaScript based user interface communication, like HTML5 and AJAX. JSON can be consumed directly in a JavaScript program just by “evaling” it, and its low overhead has also find its way into many other languages and communication requirements.

JSON is normally invoked with the JavaScript XMLHttpRequest call, normally as an asynchronous call. But sometimes, the HTML tag <script> is used to place a JSON call. In this case, the <script> tag would need a real JavaScript program instead of a JSON string. For this, many servers implement a JSON “padded” call (or JSONP), in which the JSON data is sent as the parameter of a JavaScript function. This is normally indicated by the existence of a URL parameter with the name “callback”, as seen here:


Wich gives the following output:

jsfunction({“current_resources”:4,”maximal_resources”:5,”recommended_delay”:0,”rfcsi_export”:{“rfcproto”:”011″,”rfcchartyp”:”4103″,”rfcinttyp”:”LIT”,”rfcflotyp”:”IE3″,”rfcdest”:”seppuku_NXK_00″,”rfchost”:”seppuku”,”rfcsysid”:”NXK”,”rfcdatabs”:”NXK”,”rfcdbhost”:”seppuku”,”rfcdbsys”:”ADABAS D”,”rfcsaprl”:”731″,”rfcmach”:”  390″,”rfcopsys”:”Linux”,”rfctzone”:”  3600″,”rfcdayst”:””,”rfcipaddr”:”″,”rfckernrl”:”721″,”rfchost2″:”seppuku”,”rfcsi_resv”:””,”rfcipv6addr”:”″}});

This allows full operation for function modules calls from every kind of JavaScript application.

Once the basic JSON ABAP serialization was completed, I thought it would be a good idea to give you some choice in the output format, just as Google does with most of their public APIs.

Try this:


And you will get the output of the function call in a simple XML representation:




























And  this:


In order to have the function module output in YAML format:

— #YAML:1.0





  RFCPROTO: “011”

  RFCCHARTYP: “4103”



  RFCDEST: “seppuku_NXK_00”

  RFCHOST: “seppuku”



  RFCDBHOST: “seppuku”


  RFCSAPRL: “731”

  RFCMACH: “  390″

  RFCOPSYS: “Linux”

  RFCTZONE: “  3600″



  RFCKERNRL: “721”

  RFCHOST2: “seppuku”



And  while I was at it, and remembering my Perl background, I thought it would be really fun to have ABAP just dump its data in Perl Data::Dumper format, which is quite close to JSON:


Have fun with Perl:

$RFC_SYSTEM_INFO = {‘CURRENT_RESOURCES’ => 4,’MAXIMAL_RESOURCES’ => 5,’RECOMMENDED_DELAY’ => 0,’RFCSI_EXPORT’ => {‘RFCPROTO’ => ‘011’,’RFCCHARTYP’ => ‘4103’,’RFCINTTYP’ => ‘LIT’,’RFCFLOTYP’ => ‘IE3′,’RFCDEST’ => ‘seppuku_NXK_00′,’RFCHOST’ => ‘seppuku’,’RFCSYSID’ => ‘NXK’,’RFCDATABS’ => ‘NXK’,’RFCDBHOST’ => ‘seppuku’,’RFCDBSYS’ => ‘ADABAS D’,’RFCSAPRL’ => ‘731’,’RFCMACH’ => ‘  390′,’RFCOPSYS’ => ‘Linux’,’RFCTZONE’ => ‘  3600′,’RFCDAYST’ => ”,’RFCIPADDR’ => ‘’,’RFCKERNRL’ => ‘721’,’RFCHOST2′ => ‘seppuku’,’RFCSI_RESV’ => ”,’RFCIPV6ADDR’ => ‘’}};

It shouldn’t be difficult to create your favourite data representation, look at the code and develop your own ideas.

Available options

You can add several options as part of the  query string. This is a summary of them:

  • ?lowercase=X -> outputs var names in lower case (no available when using the built-in transformation ID)
  • ?show_import_params=X -> include import params in the response
  • ?callback=<callback_name> -> returns json output enclosed in a JavaScript function call with name <callback_name> (also known as jsonp, for json padded)
  • ?format=<data_format> -> returns output in specified <data_format>, which can be: json, xml, yaml, perl. Defaults to json.

Output format is determined with the info sent by the client in the Accept HTTP header.

If specified as a query string option, it will take precedence over the Accept header.


The code is provided to you in saplink NUGG format. The code is contained in an ABAP class called ZCL_JSON_HANDLER. You just have to put it in an ICF handler. Some considerations for installation follow:

Security and ABAP roles

The ZCL_JSON_HANDLER class contains a user defined ABAP authority check object called Z_JSON. This object contains a single field called FMNAME. In order to protect access to function modules it is highly recommended that each user has a list of the function modules he or she is authorized to call with this handler. A single * will effectively allow access to all function modules.

Due to limitations in saplink, the authorization object is not created when you import the nugget. You have to manually create it with transaction SU21.

Create the ICF Service

Once you have the class installed and have created the authorization object, the next step is to create an ICF handler in transaction SICF:


Adjust logon data at will and then point your browser to the service URL. You are now ready to start!!

Acknowledgements and a bit of history

This little project doesn’t come out of nothing, and as everything that is done nowadays in technology comes from the fact that we can see further as we are standing on the shoulders of giants. There are many JSON for ABAP development projects out there, and JSON support is already built-in in the core of ABAP. This nice feature is already available in this module for the JSON and XML converters.

A great characteristic of function modules in ABAP is that they have a dynamic way of defining function parameters. Additionally, function modules are already very well suited to be used in the model of direct request->response that is so in vogue today with the Web. So we only needed a way of escaping the RFC protocol and put all this richness directly accessible to HTTP calls. I got the idea for all this from a very old blog post from Piers Harding: You don’t need to use soap to keep your rpc clean. This article is from year 2004, and actually we implemented Piers’ idea around that time, using YAML as serialization format. In 2006 we changed the main focus to JSON instead of YAML and we’ve been using that old version for a long time in internal and partner projects. Last year, some developments happening around made me have a look at all this, and could find the time to completely rewrite it cleanly and make it ready for publishing. So sorry for the delay, but it is better late than never. Hope this can still be useful to someone.

I could have never done this without the help of Juan Diaz, who opened my eyes to the incredible richness of ABAP dynamic data programming. He actually developed parts of this and is the main user of this code. Thanks a lot Juan.

I also want to thank all my colleagues at SAP that have patiently listen to me (or at least pretended 🙂 ) when I was talking about this and when I showed them the examples. I also thank them for their patience at standing at my ever changing mood: Ernesto, Félix, Miguel Angel, José, Cony, Cristina and Aviad, thanks a lot for being there.

Getting the code

The code used to be available in Code Exchange here: The link is not available anymore, as SAP decided that Code Exchange should die.

The code is now in GitHub here: cesar-sap/abap_fm_json · GitHub.

if you have problems getting the code please send me a private message.

Join the project and please report bugs and ideas for improvement. Thank you!.

You must be Logged on to comment or reply to a post.
  • César,

    thanks for pointing me to your blog. We are working in the same field and even seem to have similar preferences. For example: I appreciate that you are considering the equally useful and simple YAML format as well. And also, I am a Perl fan: When rambling through the Perl language universe, I am feeling like Alice in Wonderland, at every glance discovering a great, fascinating feature or idiom. 🙂

    Yes, many of us (the ABAP developers' community) have created own JSON parsers and JSON builders, which was an interesting experience anyway. But now, with the built-in JSON transformer, the product of this work is obsolete. If you can force the canonical JSON format (derived from the ABAP data with the identity transformation) to be used on the client side, then the "Build JSON" transformation is a three-liner, and the "Parse JSON" operation a one-liner (essentially CALL TRANSFORMATION ID). The more deviations from the canonical format you have, the more (usually small) <xsl:template>'s will have to be added to a custom XSLT transformation, as described in my blog on REST APIs (which is not a big deal either). You may find my test report useful with which I explored this technique.



    • Hi Rüdiger,

      I fully agree with you. Yesterday I just added a new method to my class to use the built-in transformation for parsing JSON, so we go in the same way. Your test report was really useful for me to understand it. I've kept the 'old' implementation mostly for the reason that the new one only works in new releases, and you know, there are plenty of old releases running out there.

      I found the experience interesting as you point. I was using this code for a long time and thought that it could add something interesting to the community, especially for the direct mapping to function modules, and also for the fact that we could use other formats, like YAML or Perl (although they could also be done with a transformation).

      Thanks a lot for your comment, and your praise of Perl!!! (that I also share).


      • Hi Cesar,

        Sorry for bothering you with this question but I´m new on this. So my question is as follows....What are the requirements (addons, components, minimun release, etc) from SAP side to get and send data from any scenario that uses JSON in the other side.

        Thanks and regards

        • Hi Diego,

          as for the release from which the built-in transformation ABAP<->JSON is available: in his recent blog on JSON in ABAP, Horst Keller writes

          WIth Releases 7.02 and 7.03/7.31 (Kernelpatch 116) JSON is supported natively in ABAP by the following features:

          • JSON-XML is a special XML format that enables JSON data to be described using an XML representation. A new format, IF_SXML=>CO_XT_JSON, has been added to the sXML Library, which enables to handle JSON using JSON-XML.
          • The canonical JSON representation asJSON defines a mapping between ABAP types and JSON. This is used in serializations and deserializations using the identity transformation ID.
          • JSON data can be specified in various forms as an XML source in the statement CALL TRANSFORMATION and a JSON writer can be specified as target. The identity transformation ID supports JSON by using asJSON.

          And Stefan Riedel-Seifert adds:

          Hello Horst,

          the information about the prerequisites about the sap system is nor precise enough. We drive 7.02 with dbsl patch level 314 and sp 06: because the corresponding interfaces and classes does not recognize the type if_sxml~co_xt_json.

          I have repaired IF_SXML and CL_SXML_WRITER and it works.

          Regards, Stefan

          • Hi Rüdiger,

            Thanks a lot for your contribution, it is really useful to have the details here. You may want to know that I have already included the ID transformation in this module for the JSON and XML converters. It is an optional change ready to be activated in the handle_request method (uncomment the lines with calls to methods serialize_id and deserialize_id). They have very much better performance especially for big and complex ABAP structures, and of course, much easier coding: one liners.



        • Hi Diego,

          If you want to use the new built-in transformation that Rüdiger comments, then you need to stick to the releases that support it mentioned in his reply. However, this module could be run with the pure ABAP JSON converter in an ABAP kernel starting from 6.40 with only small code changes. I know of people running it in 7.0SP14. Tell me which specific ABAP version you need it to run on to see if we can help.



          • Hi Uwe,

            Thanks a lot for your proposal!! it is a great idea. Are you using the delivery* function modules for getting release information? I'll check your project to see how you approached the implementation.



          • For the kernel version I'm using (the release is always the 12th entry in table "kernel_version" and the version the 15th entry). Not my invention, it's like the code in the Kernel Info Window in SAPGUI.

                CALL 'SAPCORE' ID 'ID' FIELD 'VERSION'

                               ID 'TABLE' FIELD kernel_version.

            For the Basis Release check I'm using the following trick:

                "*--- check whether current basis release supports JSON transformation ---*

                FIELD-SYMBOLS <type> TYPE if_sxml=>xml_stream_type.

               ASSIGN ('if_sxml=>co_xt_json') TO <type>.

               IF <type> IS NOT ASSIGNED.

                  RAISE EXCEPTION TYPE zcx_json_document


                      textid = zcx_json_document=>not_supported.


  • Hello, After setting up the ICF service, I am getting error 403 - you are not authorized to invoke this function module. Can anyone please help me out with this error?

    • Hi Abhishek,

      I put an authorization check in the code on purpose to make sure that the default configuration is secure. To enable it, you have two options:

      • The right one: create an authorization object in transaction SU21 with name Z_JSON and one attribute with name FMNAME. Create a role including this object. If you want full access, assign a '*' to FMNAME. Then assign the role to your user.
      • The fast and unsecure one: comment the "authority-check" lines in the method HANDLE_REQUEST. Then no auth check is done.

      I should have documented this as Uwe told me, mea culpa, sorry.

      Hope this helps.


      • Wow, thanks a lot Cesar, you made my day! It works like a charm, I have no words to emphasize how useful this adapter is for my project. Thank a ton for your awesome work!

  • Hi Cesar,

    I have a question about passing importing, changing and table parameters via POST. For example, BAPI_INCOMINGINVOICE_CREATE1 has

    Importing Parameters:




    Table parameters:












    Here, how can I specify which one is importing and which one is table parameter when doing a POST while passing them in message body in JSON format?

    • Hi Abhishek,

      You don't have to specify whether they are tables or import params. Just put them in the JSON payload. Actually, you don't even have to worry about the param order.

      The distinction between import and tables is not relevant anymore. Actually, the use of "TABLES" is currently discouraged for new function modules. It is preferred to use the table data type as import or export params. Here you're dealing with a BAPI, so you have to follow the convention, as they use TABLES params. But, from the point of view of this adaptor, there is no difference.

      Hope this helps,


  • Hello Caesar,

    Good writing and I seem to understand it well inspite of the fact that I am just an ABAPer of 3 years who tries to scratch the surface on connectivity.

    I dont know whether its totally relevant, but I'll go head and say it.

    I found this blocg Android and RESTFul web service instead of SOAP  by Michael Hardenbol really interesting and suitable for communication with few data for interchange.

    And your technique with JSON will be usefull for transporting deep structures and tables. Both are SOAP free !

      • Cesar,

        thanks for pointing me to Piers Harding's excellent blogpost. I didn't know it - it's amazing that some very straightforward things - like REST - need some years to break their way. It seems that first the detour has to be experienced exhaustively, up to its ultimate flaws. 🙁



        • Hi Rüdiger,

          Piers' post was the one that started it all 🙂 , at least from my point of view. This is the reason I included YAML as one of the formats (actually I began everything in YAML), and added JSON in 2006, when it became clear that JSON was going to be the way to go. You are right with experiencing new detours, it is often very difficult to break away from established views. I know I should have released this long ago, but I had several professional detours and the code remained languishing long time until I found the right motivation last year to upgrade it.

          Kind regards,


  • Hi Cesar,

    Is it necessary to provide the input JSON tags in all caps? For example:


         "AMOUNT": "100"


    and not


         "amount": "100"


    In my case I am passing a complex structure which is showing a weird case sensitivity.  I have a table like below with in a deep structure:



         "CURR": "EUR",

         "LOCAL_CURR": "100"




         "CURR": "EUR",

         "LOCAL_CURR": "100"


    The above JSON input is throwing deserialization error and when I make "AMOUNT" as "amount", there is no error but it does not populate this structure and returns it empty. On debugging I found that it is raising this exception at line 38 in method DESERIALIZE_ID of class ZCL_JSON_HANDLER in statement


                                  RESULT (rtab).

    when "AMOUNT" is in all caps but no hint elsewhere when it is all small case.

    I am not getting any hints for what is happening beyond it. Can you please help me out in figuring out what is going on here?

    • Hi Abhishek,

      You have just made a good point here. The ID transformation is really a canonical transformation. ABAP variable names are uppercase. So, strictly speaking there is no "amount" variable, and thus the ID transformation cannot fit it with the rtab structure and fails. As far as I know, there is no way to make the ID transformation case independent. If someone knows how to do it, I'd be really thankful if they post the solution.

      Fortunately, I was aware of this problem and wanted to give people the chance to use lowercase as well. So the "old" deserializer was developed with this in mind. So if you want the class to accept lowercase variables, you can use the JSON_DESERIALIZE method instead of DESERIALIZE_ID. Just activate it in the corresponding line of method HANDLE_REQUEST.

      The caveats of using the old method instead of the new one have been commented above, and can be summarized as follows: dependency on the deprecated CL_JAVA_SCRIPT class and better performance in the ID method. But I personally keep using the old method in several systems without any major problem (and feeding it with lowercase params 🙂 ).

      Thanks a lot for your comment. Hope this helps.


      • Hi Cesar,

        I have a situation in my project where the JSON body will be passed like with a few letters as capital and rest of them in lower case, something like




        When you pass a JSON body like this, all the ABAP variables are found to be empty. I was looking for a way to make this compatible with the JSON adapter. Can we make some changes in the javascript regex statement to resolve this issue?

          • Thanks Cesar, I will try it out and let you know, however can you please check the formatting of the code you have specified in that link? Like double quotes have became &quot;and so on - can you please paste it as plain text?

            Also, do you have any suggestions on how I can get the remote IP and hostname of machine who is calling this web service?That will be really helpful for logging as well as filtering the incoming requests.

            I really appreciate the work you are doing for this project and I am sure many will be benefited out of this. It is something which should have been built into SAP ABAP framework.

          • Abhishek,

            Click on the "Download" button in the page, and get the slnk file. Do not worry about its contents, just upload it with saplink.

            If you want to retrieve the client IP address, use the following in the HANDLE_REQUEST method:

                 remote_addr = server->request->get_header_field( name = '~remote_addr' ).

            Regarding what is included in the standard ABAP framework, from 7.40 onwards, the new REST library is worth a look:


            Thanks a lot for your praise of this module.


          • Hi Cesar,

            I am really sorry I won't be able to import your slink file. I did some modifications to the code relevant to my organization. If I import your slink file, it will overwrite my code. It will be really helpful if you can highlight your code changes or if you can just mention your changes here in comments.

          • Nevermind, I was able to figure it out. Caesar, there is another problem - the function module Z_JSON_IN does not tolerate spaces around the color (:) within JSON message (like put a space after or before a colon). It gives short dumps. Can that be fixed?

          • Hi again Abhishek,

            Can you send me by mail a copy of your function module Z_JSON_IN? I don't see this problem happening in the class exposed here.



          • Actually, the problem does not occur when using CALL TRANSFORMATION that is - when using CALL METHOD me->deserialize_id, it happens when I use CALL METHOD me->json_deserialize - I was using this method since I have to deal with lower and upper case mixed tags in JSON. Also, I would suggest to use CALL TRANSFORMATION since it would handle escape characters as well. However CALL TRANSFORMATION accepts only upper case tags. I would suggest converting all tags to upper case and then pass it to CALL TRANSFORMATION, in that way you do not have to write your own JSON parser.

          • Hi Abhishek,

            The problem you mention with the spaces before/after the colon doesn't happen even with the ABAP based converter, at least with the last revision in the slinkee file. Send me your JSON by mail to check what is happening. Notice that the method JSON_DESERIALIZE has also been updated in the slinkee.

            You have the DESERIALIZE_ID method that uses the standard transformation, it is optional to everybody to decide if they use the old converter or the new one. You know the caveats of each choice.

            I thought about going with your idea of converting the JSON var names to upper case, but I don't think it is a good idea, you have to fiddle with the input JSON string, but if you can implement it, you're more than welcome to contribute your code.

            I have several reasons to keep the old implementation, the most important being that several people are using this class in older releases that don't support the JSON transformation. You are free to choose the one that suits you better.

            Hope this helps,


          • Hi Abhishek,

            You only have to review methods JSON_DESERIALIZE and JSON2ABAP and compare with your changes.

            Please contact me directly via mail if you want a copy of the methods.



    • Hi again Abhishek,

      I've just realized that your JSON is also throwing a serialization error. You should send a complete JSON object enclosed in braces, so your JSON should look like this:



           "CURR": "EUR",

           "LOCAL_CURR": "100"




           "CURR": "EUR",

           "LOCAL_CURR": "100"


      Try this and tell me how it goes.

  • Hello,

    I'm trying to access the nugg file for this project (NUGG_ABAP_FM_JSON_HANDLER.nugg) but I get redirected to a page asking me to accept the terms of use, which I already did.  I also received a confirmation email for codex membership.

  • Hello Again Caesar,

    I have question about your idea to call a FM with an url like

    I am trying to access the service that I have coded but it is not reachable when I call it from outside the network (VPN).

    I searched around to know how to expose a webservice in SAP outside its network and I ran into a post which asked me to configure a reverse proxy as DNZ and use the proxy URL. But I am not sure how to do it. Do you have any idea on this?

  • Cesar - wow.  This is excellent - thank you.  One thing I struggled with (maybe it was me or maybe it wasn't)...  passing more than simple data types, like structures and tables. For example: a range table of plants I EQ 0010 and I EQ 0040. 

    I resolved it by improving the algorithm that maps the query string name/values to json. Now I can call a function like this:




    Or pass structured data like this:



    If interested, you can find my update to the handler here.  Please advise if I should get it to you another way.  Without code exchange I wasn't sure how to handle it.  😐

    Thank you!


    • Hi Jeff,

      First of all let me tell you that I really appreciate your contribution. I had decided early to limit the passing of parameters in the query string to simple values in the import function module definition. One of the reasons was to find the correct syntax taking into account that the idea of the query string is to pass only simple name/value pairs. So tables, and structures were out of consideration.

      But I think you've found a very interesting way to handle this case. Please allow me a few days to fully understand it and merge it into my code, so I can consider putting it mainstream.

      Please review if it works well using the semicolon as a separator. Take into account that in the query string specification the semicolon is also allowed as a separator just like the ampersand. I have to check how the ICF handles this.

      Thanks a lot and happy new year!!!


  • Hi Cesar,

    I have a question. I am good to go. But just one thing I need to confirm.

    Why I am getting tags in my output? I have just two parameters one import one export. export parameter is JSON String

    Here it is: my url:

    Output: http://my.abap.server:50000/test/ZCRM_GET_ALL_SURVYS2?iv_partner=107?format=json



    [{"survey_id":"74D4350C27D51ED3A5949E60243989BA","survey_name":"Pakistan Spine Centre - COP Survey"},{"survey_id":"74D4350C27D51ED3A7AD27308D5249BA","survey_name":"0004"},{"survey_id":"74D4350C27D51ED3A7EE3535695229BA","survey_name":"testing_audit1"},{"survey_id":"74D4350C27D51ED3A7EF7A8AE41989BA","survey_name":"this is the description"},{"survey_id":"74D4350C27D51ED3A986D98E0E9CA9BA","survey_name":"0005"},{"survey_id":"74D4350C27D51ED3AA830BA56DAFA9BA","survey_name":"Aster Audit 6M"}]



    • Hi Ahmed,

      The correct query string field separator is '&', not '?', so you should rewrite your URL as follows:

      In the way you had it written before, the "Accept" HTTP header is taking precedence, and in most browsers it contains 'xml', so the adaptor uses the XML conversion. To force JSON be sure you include the &format=json field.

      Tell me if it works now.



      • Format is JSON now. Thank a lot but I am getting '\' now.

        For example:

        {"STR_JSON":"[{\"survey_id\":\"74D4350C27D51ED3A5949E60243989BA\",\"survey_name\":\"Pakistan Spine Centre - COP Survey\"},{\"survey_id\":\"74D4350C27D51ED3A7AD27308D5249BA\",\"survey_name\":\"0004\"},{\"survey_id\":\"74D4350C27D51ED3A986D98E0E9CA9BA\",\"survey_name\":\"0005\"},{\"survey_id\":\"74D4350C27D51ED3AA830BA56DAFA9BA\",\"survey_name\":\"Aster Audit 6M\"}]"}

        Why is that so?

        • Hi Ahmed,

          Whether you believe it or not, this is the correct result. You are just putting a JSON string into an ABAP variable (probably of STRING type). So, the adapter understands that it has to quote it.

          What you really need to do is to put the Surveys in an ABAP structure in the Function Module interface. Then, let the adaptor do the conversion to JSON.

          Could you please send me your Function Module code if you need some help?



          • Hi Cesar,

            I am good to go now. Many thanks.


                "STR_JSON": "",

                "SURVY_LIST": [


                        "SURVEY_ID": "74D4350C27D51ED3A5949E60243989BA",

                        "SURVEY_NAME": "Pakistan Spine Centre - COP Survey"



                        "SURVEY_ID": "74D4350C27D51ED3A7AD27308D5249BA",

                        "SURVEY_NAME": "0004"



                        "SURVEY_ID": "74D4350C27D51ED3A986D98E0E9CA9BA",

                        "SURVEY_NAME": "0005"



                        "SURVEY_ID": "74D4350C27D51ED3AA830BA56DAFA9BA",

                        "SURVEY_NAME": "Aster Audit 6M"




          • He Cesar,

            Many thanks for that. It's working like a charm. Can you please let me know a short example of using method JSON2ABAP or how to use that. There are couple of things I need to know.

            In the table below what do you mean by VAR_NAME, JSON_STRING is a simple JSON string.

            If you can please manage, example of using this method would be great.

            JS_OBJECT TYPE REF TO CL_JAVA_SCRIPT OPTIONAL Integrated Java Script Engine
            value( ABAP_DATA ) TYPE ANY OPTIONAL
            ZCX_JSON JSON handler errors
          • Hi Ahmed,

            You don't need to use JSON2ABAP directly. Just put the ABAP structure you need as part of the IMPORTING or TABLES or CHANGING section in your function module definition.

            The adapter will take care of all this.

            If you however, for any specific reason not related to this adapter, want to use the methods directly (they are defined as static to allow this possibility), drop me a line and I'll try to help you.



  • César,

    This looks great and is a nice way to wrap function modules.  I really like the simplicity of wrapping the fm in json.

    I think one thing to be careful of is csrf attacks in a production version of this. Perhaps a csrf token could help but would make this example more complex.

    Thanks for sharing and keep up the good work,


    • Hi Alex,

      Thanks a lot for the insight. I'll be looking into this, it is a great suggestion.

      Best regards,


  • Hello Cesar,

    That is a wonderful gem blog content you have written. I have downloaded the nugg. and tried using it, works wonderfully fine. Really, Kudos to your sincere efforts.

    I have one doubt in above implementation. How do we log off this "fmcall" ( rest ) web service? When I will make a first call, it will prompt me to enter credentials. But question is how do I log out of the same?



    • Hello Harsh,

      Thanks a lot for your comments.

      Regarding the authentication, the default setting is to put the handler in an ICM service configured for basic authentication. Basic authentication does not need logout, as actually the credentials are silently sent by your browser until you close the browser session. In this configuration there is no session in the backend, so there is nothing to log out of.

      You may explore other authentication mechanisms in transaction SMICM, when configuring authentication for a given service. Note that this has nothing to do with a server based session, so whatever the authentication mechanism you use, you cannot log out of anything. You just may clear or expire the credentials in the browser.

      Just as an example, the adaptor contains an option to start a server based session. You may start a session with a query string parameter of "action=start_session". This will return a session identifier in the form of a cookie (SAP_SESSIONID_<SID>_<Client>) and will associate it to an abap backend session that will remain opened (check it in transaction SM04). All subsequent calls to the adaptor will be done in the same session context, as long as the session remains open. To explicitly close the session (logout), just make another call with "action=end_session" in the query string. Using this properly could be handy in a UI5 app.

      Note that this "feature" is untested. I mean, it works, but I haven't throughly tested it for any side effects of calling several function modules in the same abap session. There could be issues, so test it before you use it for your case.

      Best regards,


      • Hello César,

        Appreciate your help.

        I tried to follow the process you told, it is successfully ending the session on server (checked using tcode SM04), but still it is not serving my purpose.

        I want to cover the scenario, say suppose initially a user is logged in using  html5 application. Now, after performing some transactions, he wants to log out using the button. On this log out button, I am managing to clear the MYSAPSSO2 cookie successfully. But still my SAP_SESSIONID_<SID>_<Client> is there in browser. I need to get rid of this cookie to redirect my user to log in page again.

        If you can throw some more light on this...



        • Hi Harsh,

          What you want to achieve can be done the following way:

          • First, configure the ICM handler for the adaptor AND for the UI5 application to use "System Logon", as shown in the attached image below.
          • Second, when logging off, call directly the logoff handler: /sap/public/bc/icf/logoff.

          This will effectively cancel the session and will redirect you to the html logon app in the next access. Coordinate this with your UI5 or other consumer app logon process.

          Hope this helps,



  • Hi Cesar,

    Thanks for posting such an important concepts and due to this now I know one more way of exposing the ABAP FM to the External world.

    in my scenario, I have a ABAP FM call which has few structures and internal tables in input so I want to pass input data for structure and internal tables though the service call URL, please give me an idea on how to handle this case.

    Thank you,



    • Hi Jagesh,

      Thanks a lot for your words.

      Please have a look at this excellent contribution by Jeff Woehler.

      Jeff proposed a way to include tables and structures in the URL. Have a look at his code and add it to your system if you want to have this option. Just note that in the proposal nested structures are not supported.

      In general, the biggest the data set the most likely it is that you should use a POST method, so it is not recommended to put large structures in a URL.

      Best regards,


  • Hi Cesar,

    Thanks for putting this Adaptor together.   I just stumbled across this in researching JSON & SAP.  I’m excited to get this working as we are just now starting to look at some HTML5 development. 

    So I installed everything, activated the VCM and configured the ICF.  When I try it with the URL,’

    I get a VMC run error. I really have very little idea what I’m doing. My guess is that the handler is not working correctly and spewing back an error. I probably installed it incorrectly.  Is there a good way to test the handler directly?

    This is the error:

    The URL call was terminated because of an error.

    The following error occurred in system DEV : VMC run error

    The error occurred on application server WEB-DEV_DEV_01 and in work process. 11

    The termination type was: ERROR_MESSAGE_STATE

    The ABAP call stack was:


    Module: %_HTTP_START of program SAPMHTTP

    The work process error log is:

    <ErrorInfo URL="">

    <ErrorMessage>VMC run error</ErrorMessage>




















    • Hi Phillip,

      Thanks a lot for using this adaptor.

      The error you mention has very little to do with the adaptor, but probably has something to do with some incorrect configuration of the VMC (the VMC is a Java VM built inside the ABAP stack used mostly for the internet pricing module in CRM, it should be disabled by default).

      First, try to check if the error is also present with other ICF services, for example, test the /sap/bc/icf/Info service in your server to see if you get the same error.

      Next, try disabling the VMC. This is done with system parameter vmcj/enable. It should be off (unless you know what you're using it for!).

      Check also that your /sap/bc/fmcall service is correctly defined in SICF.

      Come back to me directly to my mail with the results (let's leave the comments in the blog as clean as possible 🙂 ), and I'll follow up.

      Thanks again!!


  • Hi Cesar,

        Thank you very much for sharing this. It is of great help for us(our company), if it works. If I can get your guidance in solving few issues while installation and thereafter, I will be very grateful. Your assistance would help us immensely.



    • Hi Miguel Angel,

      Thanks very much for your comment.

      First I don't think that using a function module through this adapter is the best way for handling a file upload in abap. If you insist on using this, you could always encode the file contents in base64 and put them in a string variable in the JSON string. Then your function should take care of decoding it and doing something with the file contents. However I don't recommend your doing this, and if you do, limit it to small files (<1m).

      I assume you use the file upload control in SAPUI5: JsDoc Report - SAP UI development Toolkit for HTML5 - API Reference -

      Using this control you can send the file to a URL that can handle file uploads using multiparts. The ABAP entity object supports multiparts (see CL_HTTP_ENTITY), so you should create either a ICF handler or a BSP using this feature for handling file uploads directly.

      You can find an example of a BSP that handles uploads here: File Upload in BSP Applications - Using ABAP - SAP Library. Deriving the code from there to do an ICF handler should be straightforward.

      Hope this helps.


      PS.: Si necesitas más detalles, envíame un mensaje privado, por favor. ¡Gracias!.

  • Hi Cesar,

    This adapter is very interesting way to reduce manual coding.

    I am working on NetWeaver gateway, where in we have kind of similar requirement to design gateway to get output as function module.

    The only problem I am facing with this adapter is, I can't find a way to choose different backend system.

    I have different hub system, where this handler will exist, and I need to execute function module from different system.

    your assistance would be immensely appreciated.

    Thanks in advance!

    • Hi Shefali,

      Thanks for your comment.

      This adapter is intended to be run on the backend system directly. It hasn't occurred to me before that this could be used to be able to run it as a frontend that forwards the request to a different backend, like you may do in Gateway with the "System Alias" feature.

      It could be possible to develop an option that does this, but to do it right, the correct way for forwarding authentication and other issues should be found.

      You can contact me privately if you want to discuss this further.

      Best regards,


      • Hi Cesar,

        Do you think that forwarding a request to backend would be a good idea in terms of security?

        As I am not much aware of possible vulnerabilities, but i have heard of SQL injections, can that be a problem?

        also, how to call FM dynamically in different backend with RFC, as SAP allows either CALL FUNCTION with parameter-table(dynamic) or CALL FUNCTION with DESTINATION?

        Thanks in advance!

        • Hi Shefali,

          Sorry for coming back to you so late. In the adaptor you can only call local function modules, no "remote" functions. You can create a function wrapping a call with destination to other system.

          I haven't given much thought at using the adaptor "à la Gateway", as a frontend, but it could be a good idea. Actually, since you wrote this, several other persons have asked me about it too.

          Hope this helps,


  • Hi Cesar,

    We have been using this for more than a year now and it has been working great. Thanks for creating this. Recently, I noticed that it is not giving all the values in handler module while converting from JSON to ABAP internal table when the table has more than like 4k rows. Do you see a similar issue? To recreate, try passing more than 4k rows in your JSON for one of the table parameters when calling any web service in your system.

    • Yes, there is a bug in the SAP Standard Javascript engine (Kernel function). I haven't found a solution for this yet.

      Currently you have to split the JSON files into smaller pieces.

      (background: the class cl_java_script is not ment for public use anymore and therefore I'm not able to open an official SMP issue).

      But maybe César may open an internal issue if he has the connections.... 😘

      • Thanks for the reply Uwe. Can we rewrite JSON2ABAP method and use ABAP for parsing? ABAP supports regular expressions, so just a thought here in case any one has tried this. Even if we do not use regular expressions, maybe we can write our parser code from scratch. Let me know your thoughts.

          • I just trying to understand the bug with the javascript engine. So this is a limit on one internal table or the entire JSON message? I mean, I have one table parameter currently on my JSON message which has large number of records. Can I split it into say 4 internal tables in the same JSON call each having 1000 rows(upper limit of number of records is known)? Or it has to be 4 different JSON calls?

          • You have to make sure, that the result does not exceed the limit. You may, for example, work with an "offset" parameter or something similar in your function -> yes you have to call the function 4 times.

    • Hi Abishek,

      Yes, at it is pointed by Uwe there are some limits in the JavaScript library we are using for "deserializing" JSON.

      Actually, I've been able to determine two limits:

      1. The maximum size of the JSON document that the library is able to accept. I have to check the exact limit for this, but I saw something around 1MB, may be dependent on version. In your case you seem to be reaching this with a message containing 4,000 rows, but it is not the number of rows but the size of the total message,

      2. The maximum size of a JSON field. Uwe and I tested it, and the limit is 127KB.

      So, for now, the only approach is to use smaller messages when calling the adaptor.

      This happens with the JavaScript based deserializer. I haven't tested it with the "transformation ID" deserializer, so I can't tell what happens there. I'll be doing it soon.

      Best regards,


      • Hi Cesar -

        When i try to import NUGG_ABAP_FM_JSON_HANDLER.nugg i am getting "Plugin for object type TABL is not installed on this system" error. I have imported both SAPlink_Daily.nugg as well as SAPlink-plugins_Daily.nugg and trying to import NUGG_ABAP_FM_JSON_HANDLER.nugg using ZSAPLINK...but it is not helping. Can you please advise?

          • Thanks for your response Fetzer. Sorry for missing to mention about that. When trying to activate, I was getting the below error.

            Class ZCL_JSON_HANDLER,Method IF_HTTP_EXTENSION~HANDLE_REQUEST    57    @0A\QError@
            Type "ZICF_HANDLER_DATA" is unknown  

            But now after i see your response 🙂 i tried to omit Z_CL_JSON_HANDLER and activate. It activated fine and later imported NUGG_ABAP_FM_JSON_HANDLER.nugg successfully too....but i am surprised to see in the report output that it installed Z_CL_JSO_HANDLER :-(. If Z_CL_JSON_HANDLER is part of this .nugg file ...not sure how it was there even before importing this .nugg file. may be it is because of me trying different things out of sequence?

            Anyway, the issue i have now (after importing json_handler.nugg) is I am not unable to activate Z_CL_JSON_HANDLER as it still complains ZICF_HANDLER_DATA is unknown.  Can you please advise?

            Thanks for your help in advance.

          • Cesar advise to manually activate the structure ZICF_HANDLER_DATA in SE11 and the above error is gone.

            But now, I have another issue. I have created a service in SICF and maintained the login details and maintained ZCL_JSON_HANDLER in Handler list tab. After activating the service...when i try to test the browser window opens but immediately takes me to View Downloads page where it asks me to "save" doesn't do anything after hitting save button also...nothing to save and doesn't go anywhere. Can anyone please advise?

          • After correcting the incorrect port numbers in the worked fine!!. i am able to see the output of RFC_SYSTEM_INFO.

            However, i tried to call our custom fucntion module which returns data in four table and each table having 2, 48, 48 and 674 entries respectively....The app is now breaking with the below message....

            XML Parsing Error: not well-formed

            <<Complete url as entred in the browser along with inputs to the FM as url parameters>>

            <<the whole xml structure as one big line...>>

          • Hello Venkat,

            It seems that you have successfully set up the adapter. The error which you are telling has to do with forming input parameters to function module using XML. You are not forming the input parameters correctly in XML.

            Let me know if further help required.



          • César -

            Sorry for the late reply. Please check the screenshot. Similar error in Firefox and Chrome also. But format=json and format=yaml is working fine in all three browsers. i guess XML is just a browser issue and would work fine when called inside the code?IE.JPG

          • Hello Venkat,

            I'd like you send me also the code to the function module, and also the JSON output (save it to a file). Please send them to my personal mail.



  • Hi all,

    We are getting "Type "CL_ABAP_CODEPAGE" is unknown" error in method "SERIALIZE_ID" (row 68) while we try to activate ZCL_JSON_HANDLER Class.

    We are new on this. Could you help us?

    Best regards and thanks in advance!

        • Hi Rubén,

          The ID standard transformation is not available for that ABAP version, it requires a minimum of 702. For using this adapter with 700, you must use the class built-in ABAP based serializers. For this, do the following:

          - make sure that the lines in HANDLE_REQUEST calling serialize_id and deserialize_id are commented out,

          - comment out the code in methods serialize_id and deserialize_id,

          - activate the class.

          That should make it work in 700.

          If you need more help, please contact me by mail.



    • Hi Tiago,

      This is an excellent contribution!!

      Everybody should refer to it in case of doubts about how to call this from JavaScript.

      Thanks a lot Tiago!!


  • Hi Cesar,

    Nice blog and must say lot of comments. Not sure if i have seen these many comments on any other sdn blog.

    One question, as i was not able to go through all the comments. Since we already have gateway, and I dont think it is a very costly setup. What pushed you to create your own class?



    • Hi Pranav,

      Thanks a lot for you nice comments!

      As I explained in the blog, I actually started what whould later become this in 2006, so we had no alternatives by then. When I released it in 2013 I was actually motivated by the appearence of Gateway. I had great expectations on Gateway, but many people contacted me to tell me that they thought that sometimes the oData approach could be more cumbersome to make some tasks than using just simple function calls.

      Let me quote Tiago in his GitHub page:

      Some systems have a lot of function modules already developed and wrapping them in Odata services would be a prohibitive amount of work. On the other hand, it is also common that the gateway is the backend server (and not a separate instance). On these systems, it makes a lot of sense to call the function modules directly.         

      I could add more making for a very long debate. In my opinion, oData and Gateway are good as long as the kind of service adapts well to the oData model: navigation from item lists to item details and leveraging this ability to automatize some funcions in the user interface (ie. automatic scrolling, search and filtering of the results, navigation from lists to item detail, automatic generation of forms from metadata, etc.).

      Many uses in AJAX-like applications are not suited very well for this model. In many cases a simple model of request-response suits better. Additionally, you can also employ highly nested structures (AKA JSON documents) with this adaptor, whereas it becomes very limited to do this with oData and Gateway (lots of limitations on the use of complex structures and use of "deep inserts").

      Finally, the ease of reusing existing code already developed in Z functions at plenty of customers is probable the bigger push to use this adapter.

      Hope this helps.

      Best regards,


  • Dear César,

    at UI5con in Frankfurt there was a presentation by Mark Schmale on "Combining UI5 and SAP LO VC for fun and Profit". The best thing of this presentation was that he used the JSONRPC Service that is delivered as part of SAP Gateway in the SICF Path /sap/gw/jsonrpc. Check out my Tweet for screenshots. The only tricky part is that your request must include a CSRF-Token. Such a token can be retrieved by calling any standard SAP Gateway service.

    Best regards


    • I don't think, that this service should be active in the system (but you may clone the underlaying handler and restrict it to specific function modules)

      • I even think that this approach should be used anyhow. SAP ABAP systems should be exposed by easy to consume, standard or custom build ODATA services to also benefit from the ODATA support in UI5.

  • Hi Cesar,

    Fantastic article. It helped me a lot. Quick Question - How can I generate a 'WADL' so my partners can create a consumer scenario with all the data elements loaded into their tools/system.


    • Dear Rahul,

      I think you mean a WSDL. Please do not use this approach and stick with the SAP standard tools and provide a WebService by creating it in SE80 or OData via SAP Gateway (Transaction SEGW).

      Best regards


      • Dear Gregor,

        Thank you for your time and recommendation. I agree with your comments that using NW Gateway is our best bet. I meant WADL though; our partners using PeopleSoft have shown me their screen and they have some sort of WADL consumption screen. Looks like WADL is advocated by Oracle side of the house for Restful web services, but W3C has not standardized yet. Anyway, we are proceeding with SAP Standard tools/webservice.

        Best Regards,


        • Hi Gregor, Rahul,

          As a matter of fact, it is WADL, not WSDL (Web Application Description Language).

          It is funny that I was considering adding WADL to this adaptor and was studying its feasibility with one colleague one year ago. Finally, we decided against doing it, for several reasons:

          First, this adaptor is not providing RESTful services. There are no different actions related to the request method used in the HTTP call (unless you activate a trick that is included in HANDLE_REQUEST and develop your function module for it).

          Second, WADL is not fully standarized and very few tools make use of it, and none among SAP tools (except SAP API Management, Apigee, which does - actually that was one of the reasons I considered it). And the fact that Oracle advocates it doesn't help either 😉

          The fact is that if your requirements include full documentation, interoperability, standarization, and code generation for consumer apps, you're probably better off with the standards supported in SAP, like SOAP/WSDL and oData, as Gregor suggests.

          On the other hand, if you are in full control of your development landscape and it is enough for you to distribute an example for the call, you may well use this adapter, especially if you want to reuse existing modules. Some people I know are happy using this with SAPUI5 apps, and some others even mix oData calls with calls to this adaptor.

          Instead of WADL, I also considered JSON-RPC. I'll have a look at the jsonrpc gateway service that Gregor suggested above.

          Best regards,


  • Hi César,

    thank you for sharing your work. We are currently looking for a lightweight alternative to JCo and your adapter (or the above mentioned json-rpc service) seems to be very promising. Both are working great in my first tests but there is one feature I couldn't find so far: for our app we need transactional RFCs for locking and to rollback changes in case of errors in later RFCs. Is something like that possible with your current implementation?

    For the json-rpc service I couldn't find any documentation apart from the screenshot Gregor posted.

    Best regards,


      • Dear Gregor,

        thank you for your input. I know that REST and JSON-RPC are stateless (btw. JSON-RPC is not per se RESTful, but this is another topic).

        The problem is that we already have alot of ABAP functionality, which would be hard to translate to an OData interface.

        But fortunately I've found the needed functionality in both versions (the adapter from this blogpost and the json-rpc service).

        For the JSON adapter you only need to add ?action=start_session and ?action=end_session to the parameter list, to start and end a session in which the LUW doesn't change. (this sets a cookie for the session management)

        For the JSON-RPC service there is something like a "virtual function module" to start and end a session. This could also be interesting for people, who doesn't need a stateful connection because it's a good way to get the csrf-token. If you send:



          "method": "JSONRPC.INIT",

          "params": {

            "SESSION" : {

              "STATEFUL" : "enabled",

              "VIA" : "cookie", // this can also be "url" for url encrypted session ids

              "TIMEOUT" : <timeout>



          "id": <id>


        you get this answer with a session id in the cookies:


          "jsonrpc": "2.0",

          "result" : {

            "ENDPOINT": "/sap/gw/jsonrpc",



                "NAME": "X-CSRF-Token",

                "VALUE": <token>




              "STATEFUL": "enabled",

              "VIA": "cookie",

              "TIMEOUT": <timeout>



          "id": <id>


        To end the session just send "method" : "JSONRPC.END" with no params.

        I hope this saves someone the time I needed to dig into the code 😉

        Best regards,


        • Hi Christoph,

          I'm happy that you reviewed the code and found the start_session and end_session options.

          Please note that I just did some little testing on them, but not enough to confirm that they may serve all purposes. That's why I didn't document them by the way. They just use the SAP standard session handling for HTTP, the same that is used by the stateful BSPs, so they should work, but your application should take care of the cookies, the operations done in the session lifetime and should take care of the session auto expiration (something that is normally controlled by the BSP framework).

          You and Gregor are correct pointing out that REST is inherently stateless, as is the web in general, so any way of carrying session information on top of HTTP is somehow a hack, although it is today so widely done as to be considered a standard.

          This adaptor is not RESTful, and it is not its purpose to be it (there are ways that you could make a function endpoint that could implement a RESTful service on top of a function module, look for the corresponding section in the code). So it is more akin to JSON-RPC in the way that it just exposes an endpoint to make a call to a function module with input and output serialized in JSON payload.

          Please do not hesitate to contact me if you find any issue with the use of the start and end session options.

          Best regards,


      • Hi Gregor,

        As far as I understood it, Draft Documents are not really transactions, but a way of handling transient storage for an entity in the application. I don't know if they support locks, so they are not exactly the same as a transaction in ABAP.

        Moreover, it seems that they can only be used from the Smart Templates.

        Do you have more information on them?



    • Dear Juan,

      why do you want that? By having JSON or XML you can implement a HTML5 Frontend which consists of static and due to that cached HTML, CSS and JavaScript that will render the dynamic part returned from the Server to the page.

      Best regards


      • Thanks for the quick reply.

        I am new to web services so bear with me.

        Our current PR approval workflow process send an workflow email to approvers with a link  which starts the SAPGUI. I want to simply to this by allowing the users to simple click on the webservice for approval.

        This web service is quite simple that it calls a FM with a single importing parameter(PR number) and returns whether it was approval process was successful or failure.

        When the user click on this web-service ,  I want to be able to render the return message into a pop up for the user.

        implement a HTML5 Frontend  - Do you mean to have intermediary frontend that calls SAP  and renders the return JSON  message into HMTL?

        • Hi Juan,

          perhaps it would be worth a look into the standard SAP Fiori app for PO approvals. There are no additional licensing costs for Fiori. The most simple and straight forward solution for your issue should be using a BSP.

          Best regards


    • Hi Juan,

      It should be possible, just copy the ABAP2XML method to ABAP2HTML and modify the code accordingly. But, HTML is for formatting layout, so you will have to imagine to which HTML tags you would map any data. It is not worth to do it nor is the adaptor the place to do it. As Gregor said, you should be doing that transformation in JavaScript in your HTML5 app. Or implement a simple BSP or WDA directly.

      Do you mean to have intermediary frontend that calls SAP  and renders the return JSON  message into HMTL?

      More or less this is the model currently used for HTML5/JavaScript/CSS apps in vogue today.

      Take your time to learn it, we have all been new to something at one point of our lives.

      Best regards,


      • thanks for the reply.

        is it possible way to  pass the sap user id and password in the JSON(or url) instead of hardcoding it the SICF node?

        • Dear Juan,

          never pass username & password via the URL. You should look into options (X.509 Certificates, SPNEGO, SAML) to enable secure Single Sign On for your ABAP Stack.

          Best regards


        • Hey Juan!

          It looks to me that you are quite not ready to fly yet!!

          What you have proposed is just one of the many mishaps you may come across if you are not careful with security.

          Instead of telling you how to solve this problem, I'll tell you to take some time to learn about it. Believe me, any time you dedicate to security is more than worth it.

          You got some good hints from Gregor. Please look for topics around web security and when you feel prepared, go look at Authentication - RFC/ICF Security Guide - SAP Library to get more information SAP related.

          We are here to help you, but please, do your homework first!!

          Best regards,


          • Thanks Gregor and Ceasar for the your advices. I will more into the security measures.

            I have set up the authority check as you have described and its working as expected.

  • Hi Cesar,

    we have to load currency exchange rate from a URL in a JSON file format, I did not find a good example that would fit my string, can you guide me ? data look like this.

    Thank you.

    any clue how to also get the output of the URL into SAP directly would be appreciated?


  • Dear Cesar,

    I'm new to web technologies involving SAP. Please forgive me if what i say seems contradictory.

    I'm working on an old vertion of SAP where REST solution isn't provided yet (sap_basis 702). I already have implemented a note that allows me to use xslt_tool for coding rest.json files such as :


    What I need to do is use an external API where model may be like tyis : "http2//{hostname}/webmarketing/<service>/v1/notify/<service_point_id>".

    What sort of change should I make in the code you provided that may permit the transfer of rest.json data to the external site ?

    I know how it may works with Soamanager and WSDL files, but how could it works with rest.json ?

    Thanks for your help.

    Best regards,


      • Hi Sandra,

        thanks. I must admit I didn't undestand that.

        to test API do I need add on IW_FND and transaction /IWFND_/GW_CLIENT ?

        without it how may I test CL_HTTP_CLIENT with my program ?

        Best Regards,

        Jean-François Parmentier.

        • Sorry, I can't help for the Gateway application.

          You should better create a new thread in the Connectivity forum, I don't think your question is related to this blog post.

  • The JSON Adaptor does not seem like large XSTRINGs.  In the JSON2ABAP method the js_object->execute bombs with no error message when trying to send in to much data. 

    I ran the script in JSFIDDLE with the large data and it ran without any issues.

    Any idea how to correct this without limiting the data?

    • Hi Vince,

      Unfortunately, this limitation has been known for a very long time. It is due to the fact that the JSON2ABAP method in the adaptor is using the CL_JAVA_SCRIPT class and there seems to be a hardcoded limit in the maximum size of a variable when passed from the ABAP to the JavaScript context in the embedded SpiderMonkey engine. The limit seems to be around 120k. It does not have an easy solution, as SAP decided to deprecate the CL_JAVA_SCRIPT class, and while still included in the system, it is no longer maintained, which is a pity, by the way.

      But wait!, there is a solution already built into the code. Uncomment line 262 of method HANDLE_REQUEST and comment out line 261 (substitute the call to method me->json_deserialize  with a call to method me->deserialize_id). This way, the adaptor will use the ABAP built-in JSON deserializer transformation that has no such size limits. Just be careful that when you do that, the adaptor will be very strict with the JSON it takes, you will have to feed the adaptor with the complete JSON structure of the call. If that is not a problem for you, then do this change and it should work.

      Please keep me informed if the solution works for you.

      Best regards,


      • When you say the complete JSON structure are you saying the inputs and output (Imports, Exports, Tables, etc) have to be in the call?  Do you have an idea of how a such call would look like.

        • Vince Tebano wrote:

          When you say the complete JSON structure are you saying the inputs and output (Imports, Exports, Tables, etc) have to be in the call?  Do you have an idea of how a such call would look like.

          Hi Vince,

          It looks like that the built-in transformation is now working well, and it is no longer needed to build a full structure in the call. Sorry for this.

          Did it work any better with the built-in transformation regarding the size limit? I'd like to hear from you.



  • Hello Cesar,

    I have implemented the JSON service adapter in our SAP development system and working absolutely fine. However, after moving the transports to quality system, the third party system which is making the call to SAP is not receiving any parameters in the response. But the connection between third party and SAP is perfect, they are getting response but without any return parameters. Please help me how to solve this issue. The same is working perfect in development system.


  • Hi Cesar,

    I have been using this “gem” since 2013 in Netweaver 701. Like Vince Tebano says above, I have had problems using large XSTRING parameters (i.e. transfering binary files), but tweaking the code I have solved the problem.

    Now I am using this adapter in Netweaver 740 SP9, so I can use the DESERIALIZE_ID and SERIALIZE_ID methods and avoid the old method JSON_DESERIALIZE. This, in theory, would solve the issue with large XSTRING parameters.

    But when I use the DESERIALIZE_ID method I get the exception
    CX_XSLT_DESERIALIZATION_ERROR, even if I use a simple function module like DATE_GET_WEEK.

    I use this call


    and the JSON for the transformation is {“DATE”:”20161214″}

    Where is the problem?


    Víctor Hernández

  • Hi Cesar,

    First I want to congratule for the great job. I think it’s a very useful tool!!

    I have a little problem, I would like to know how to send parameters to SAP of a list of values. I have one of the import parameters of the function module defined as table type and the line is defined as elemental type (in this case the type is EQUNR), then I have the following import parameter:

    I_EQUIPOS type TY_CCM_EQUNR (list of EQUNR).

    I’m trying to send a list of values via POST method with the following JSON string:

    “I_EQUIPOS”: [

    but it doesn’t work.

    I’ve debugged the call and my function module receive any value in I_EQUIPOS.

    Can you help me?


    • Hi,

      Thanks for your response, but I'm not able to find how to send you a private mail, sorry.

      Please, give me some clues to find how to send the private mail.


  • Hi Cesar,

    I have implemented the JSON service adapter in our SAP development system and get the syntax error in the class ZCL_JSON_HANDLER in method 'DESERIALIZE_ID'.

    Line # 40 gave me the error,please help me to solve the issue.

    Inderpreet Singh



      Same issue...

      I'm trying to install the ABAP-JSON with the transport I downloaded from:

      I tried to import the transport with STMS transaction and I'm getting an error message on method "DESERIALIZE_ID" about line 41:
      data(reader) = cl_sxml_string_reader=>create( json_xtext ).

      The error is:
      Field "DATA" is unknown. It is neither in one of the specified tables
      nor defined by a "DATA" statement. .

      Here is the screenshots:


      Any help will be great.
      Miki Barzilay

      • You have a 7.31 system, and the tool was developed on a 7.40 system. So, you have to adapt/backport the tool. For instance, you have to replace the following:

        data(reader) = cl_sxml_string_reader=>create( json_xtext ).


        DATA reader type ref to IF_SXML_READER.
        reader = cl_sxml_string_reader=>create( json_xtext ).


        • Next issue is referring to:

          data(writer) = cast if_sxml_writer( cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ) ).

          It seems, in 7.31 we have to change it to:

          writer = cast if_sxml_writer( cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ) ).

          But then we still got the following error:

          “Field “CAST” is unknown. It is neither in one of the specified tables”


          Please advise.






          • Yes of course, there are many many differences between 7.31 and 7.40. If you want to adapt the code, you should understand 7.40: I suggest you to reading Horst Keller blogs about 7.40

            data(writer) = cast if_sxml_writer( cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ) ).

            corresponds to (cast = down cast) :

            DATA writer TYPE REF TO IF_SXML_WRITER.

            writer ?= cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).

          • Another one is:

            data(attributes)  = cast if_sxml_open_element( node )->get_attributes( ).

            How should it be converted into 7.31 syntax?



  • Hi Cesar Martin,


    Thank you for sharing this information. We are able to call a function module and also pass variables via URL. All work fine if import parameters are simple parameters. (like they take only one value)

    Is it possible to pass values via URL to a variable which is of type table with two columns. Something like below

    IT_CONTEXTS     - Variable Name


    CONTEXT_NAME - Value 1
    CONTEXT_TYPE  - Value 2


    I am struggling to find a correct format for this to pass it via URL.



    • Hi Amit,

      Jeff Woehler in a previous comment already proposed something similar and implemented some code to handle it.

      I personally prefer restricting the use of the query string just for plain variables in the import area, and use POST for structures and tables, but I see the point of having the option in the query string. Please feel free to contribute the code.




  • Thank you for nice article but I have some problem there is error on method: IF_HTTP_EXTENSION~HANDLE_REQUEST it says ‘Type “ZICF_HANDLER_DATA” is unknown.’ .

    I have checked in se11  but I couldn’t found type: ZICF_HANDLER_DATA.

    Could please help to fixed this error.


    Best Regards,

    O. Fajilago


  • Hello César,

    thanks for the great work, I was exactly looking for a funktion like this, since I have many function module based interfaces that I can now supply to the web-world. The basic "rfc_system_info" call is working however I am struggling with calling my custom fucnction modules.

    They have a structure like:


    Doing the call I get the following error message:

    I get a su53 error like this. Please check the "//" within the authorization Error

    Has anyone an idea how to overcome this?

    Best Regards


    • /
      • Look at your function module name. If you use slashes, the function module name is mapped to one in a namespace. Check that the function //<namespace>/<function_name> exists.

  • Dear Cesar,

    Superb write-up and excellent piece of work.

    You saved lot of efforts from our end to convert existing SOAP webservices returning XML data to RESTful webservices with this adapter.

    Keep sharing….cheers & many thanks!


    Shaurya Jain