It is very simple to create a webservice using only ABAP, thanks to Naresh Bammidi that showed us the way!

đŸ™‚

Basically, we start by creating a new class in SE24 implementing interface IF_HTTP_EXTENSION.

7.JPG

Then, we just implement the method handle_request.

The trick is to concatenate everything in a single string, using the JSON style, and set the content type by using the method set_header_field.

Check my sample code bellow:

METHOD if_http_extension~handle_request.

     CONSTANTS: c_object_start TYPE c VALUE ‘{‘,

                c_object_end   TYPE c VALUE ‘}’.

     DATA: lv_path_info      TYPE string,

           lv_request_method TYPE string,

           lv_response_data  TYPE string.

     DATA: it_inputparams TYPE tihttpnvp,

           ls_inputparams TYPE LINE OF tihttpnvp.

     DATA: lv_ebeln TYPE ekpo-ebeln,

           lv_ebelp TYPE ekpo-ebelp,

           lv_matnr TYPE ekpo-matnr.

     FIELD-SYMBOLS <fs_param> TYPE LINE OF tihttpnvp.

     “Get request info

     lv_path_info = server->request->get_header_field( name = ‘~path_info’ ).

     lv_request_method = server->request->get_header_field( name = ‘~request_method’ ).

     “Only GET is allowed

     IF lv_request_method NE ‘GET’.

       CALL METHOD server->response->set_header_field( name = ‘Allow’ value = ‘GET’ ).

       CALL METHOD server->response->set_status( code = ‘405’ reason = ‘Method not allowed’ ).

       EXIT.

     ENDIF.

     “Get GET parameters

     CALL METHOD server->request->get_form_fields

       CHANGING

         fields = it_inputparams.

     UNASSIGN <fs_param>.

     LOOP AT it_inputparams ASSIGNING <fs_param>.

       TRANSLATE <fs_param>-name TO UPPER CASE.

     ENDLOOP.

     CLEAR: lv_ebeln, ls_inputparams.

     READ TABLE it_inputparams INTO ls_inputparams WITH KEY name = ‘PO’.

     lv_ebeln = ls_inputparams-value.

     CLEAR ls_inputparams.

     “Empty parameter

     IF lv_ebeln IS INITIAL.

       CALL METHOD server->response->set_status( code = ‘404’ reason = ‘Empty parameters are not allowed’ ).

       CALL METHOD server->response->set_cdata( data = ‘There are one or more missing parameters’ ).

       EXIT.

     ENDIF.

     “Start of response data

     lv_response_data = c_object_start.

     “Add element: PO

     lv_response_data = | { lv_response_data } “PO”:” { lv_ebeln }”, |.

     “Add array: ITEMS

     lv_response_data = | { lv_response_data } “ITEMS”:[ |.

     “Add items

     SELECT ebelp matnr

       INTO (lv_ebelp, lv_matnr)

       FROM ekpo

       WHERE ebeln = lv_ebeln.

       lv_response_data = | { lv_response_data } { c_object_start } “NITEM”:”{ lv_ebelp }”,”MATERIAL”:”{ lv_matnr }” { c_object_end },|.

     ENDSELECT.

     IF sy-subrc = 0.

       SHIFT lv_response_data RIGHT DELETING TRAILING space.

     ENDIF.

     “End of array

     lv_response_data = | { lv_response_data } ] |.

     “End of response data

     lv_response_data = | { lv_response_data } { c_object_end } |.

     “Set JSON Content-Type

     CALL METHOD server->response->set_header_field( name = ‘Content-Type’ value = ‘application/json; charset=UTF-8’ ).

     “Set Response Data

     CALL METHOD server->response->set_cdata( data = lv_response_data ).

ENDMETHOD.

After that just publish it in SICF, into Handler list and test it.

3.JPG

I tested it in SoapUI 5.2.1.

6.JPG

Reference doc: http://scn.sap.com/docs/DOC-46463

To report this post you need to login first.

3 Comments

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

  1. RĂ¼diger Plantiko

    It really is that easy.

    And it is a great moment when you made it work the first time and see how easy it actually is!

    But the next steps would be

    • Make one service responsible for different types of requests – which leads to some kind of parsing the request and delegating a work to a “worker class”.
    • Instead of producing JSON with strings, produce it the right way with transformations or with a builder class working on base of IF_IXML_DOCUMENT. Find examples for the different ways to do it in the ABAP docu! It is easier, less error prone, and the right level to work with “foreign” data formats like JSON or XML.
    • For each request, different resonse data types may occur. Separate the general HTTP communication, i.e. transforming data to JSON and putting them into the response, from the specific tasks of the handler which refer to concrete data in the ABAP world and retrieve ABAP data to the general part.

    I outlined some of these tasks in this blog from 2013. For some of the things described there, there are better ways in the meantime. The main gap of that blog is that there even is a complete API framework for restful services nowadays.

    Study the docu for more details on these issues.

    Best regards

    Rüdiger

    (0) 

Leave a Reply