EPO Consulting Wiki - EPO_Connector_-_how_to_provide_a_simple_JSON_webservice


This documentation shows an easy example how to provide a JSON webservice. There is also an example how to consume a JSON webservice.

There are several ways how to implement a webservice. This example shows how to use the GFMC (Generic Function Module Call) of the EPO connector in order to expose a function module as a JSON web service on a SAP server.


Function module Z_EPO_JSON_STRING

In this example, we implement an 'echo' webservice, which takes a string 'STRING' and an additional parameter 'REVERSE' to reverse the argument. The result is passed in the parameter 'RESULT'.

FUNCTION Z_EPO_JSON_STRING .
*"----------------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     REFERENCE(STRING) TYPE  STRING
*"     REFERENCE(REVERSE) TYPE  FLAG
*"  EXPORTING
*"     REFERENCE(RESULT) TYPE  STRING
*"----------------------------------------------------------------------

" string - webservice:
" return the string;
" if 'reverse' is not an empty string, reverse the string

  DATA:
    lv_reverse TYPE flag,
    lv_char    TYPE char1024.


  " conversion to character in order to handle an string with spaces
  lv_reverse = reverse.

  IF lv_reverse IS INITIAL.
    " simply copy:
    result = string.
  ELSE.
    " reverse that string
    " note: STRING_REVERSE does not handle strings..
    lv_char = string.
    CALL FUNCTION 'STRING_REVERSE'
      EXPORTING
        string          = lv_char
        lang            = sy-langu
      IMPORTING
        RSTRING         = lv_char
      EXCEPTIONS
        OTHERS          = 0  " ignore errors
              .
    result = lv_char.
  ENDIF.

ENDFUNCTION.


Parameters

For a clean interface, there are only importing and exporting parameters. We do not use: changing- / tables parameter and do not raise exceptions. The error handling should supply readable error messages into exporting parameter(s).

Note: usually, the importing/changing/tables/exporting parameters are mapped to separate JSON sub-objects. If there are only importing and exporting parameters, we can use a transformation in order to receive only importing parameters and to return only exporting parameters (see 'field mapping').

 

JSON request and response

The import parameters 'STRING' and 'REVERSE' should be posted in such a JSON structure:

{
  "string":"test",
  "reverse":"X"
}

The result should be returned in such a JSON structure:

{
  "result":"tset"
}

 

SICF settings

In SICF, it is required to activate an element, which uses the EPO handler: activate the 'epo1soa' / 'jsonhandler'

ClipCapIt-200506-150450.PNG

..which uses the /EPO1/JSONHANDLER handler:

ClipCapIt-200506-150632.PNG


Logon data: supply the SAP-client (otherwise, it would be necessary to specify the SAP-client as URL parameter). If there are multiple SAP-clients to maintain, it would be possible to define a separate SICF element for each client - or to specify the sap client as URL parameter (e.g. '?sap-client=100').

 

EPO Connector Customizing

With the definition of a service / operation, the EPO framework will be enabled to make a function module accessible as a webservice.

Start the transaction /EPO1/EXC, which is an area menu


Creation of number ranges for EPO Connector logging

If not exists, define two number range. For EPO services, we use the number range '00' for incoming services and '01' for outgoing services

Transaction /EPO1/EXC

  • EPO Connector Configuration
  • Maintain default number range /EPO1/NOR


Create the intervals '00' and '01'':

  • 00: 0000100000000000 0000199999999999
  • 01: 0000200000000000 0000299999999999

 

Creation of the EPO Connector Service Name

Transaction /EPO1/EXC

  • EPO Connector Configuration
  • In: Maintain EPO Runtime service configuration


Create a new service 'EPOFMJSON_STRING_REVERSE':

ClipCapIt-200506-151935.PNG


Important fields:

  • Direction of service: this is an inbound service (called from outside)
  • Operation mandatory: requires a defined operation (otherwise, ANY function module could be called by this service - which is not nice on a productive system)
  • Default operation: allowes us to omit the specification of the operation name as URL parameter

 

Creation of the EPO Connector Operation

When using GFMC, the operation is mapped to the function module. Otherwise, the operation could also be mapped to another function module, using the menu entry GFMC: Change processing FM for given operation.


Transaction /EPO1/EXC

  • EPO Connector Configuration
  • Inbound Service Configuration
  • In: Maintain EPO Runtime service configuration


Create a new operation 'Z_EPO_JSON_STRING'

ClipCapIt-200506-152850.PNG


Important fields:

  • Number range object, Number range number: used to identify individual log lines
  • Processing type: S - synchronuous, will be handled immediately
  • Loggig of the EPO header (implicit), Message (in- and outgoing), Meta data (in- and outgoing)
  • Processing FM: /EPO1/GFMC_JSON_PROCESSINGFM handles the JSON processing
  • XSLT in: /EPO1/EXC_JSON_IMPORT_STRUC creates the 'IMPORT' JSON sub-object for input parameters
  • XSLT out: /EPO1/EXC_JSON_EXPORT_STRUC removews the 'EXPORT' JSON sub-object from exporting parameters
  • Field mapping: use the configurable field mapping (otherwise, all JSON field names will be in uppercase)
  • Response format: t - using a transformation in order to create the JSON response
  • Response strip: 1 - remove empty fields/table lines from the response

 

Field name mapping - /EPO1/FIELD_MAP

All the names of the JSON request / response has to be mapped to ABAP fields. To make the life easier, we will use the table /EPO1/FIELD_MAP in order to maintain the mapping. In our case, the field names are very simple, so a 'lowercase' format would be sufficient.

For this example, we will simply use the [lowercase] - mapping: every ABAP letter will be mapped to a lower-case JSON letter.

ClipCapIt-200506-155743.PNG


Note: when using the [camelCase] or [CamelCase] - mapping for inbound together with the IMPORT - transformation /EPO1/EXC_JSON_IMPORT_STRUC, the field IMPORT needs to be mapped to IMPORT explicitely (otherwise, the 'IMPORT' - field name will be mapped to '_I_M_P_O_R_T' or 'I_M_P_O_R_T', which will not work):

ClipCapIt-210921-161356.PNG

Alternatively, use the camelCase - IMPORT - transformation /EPO1/EXC_JSON_IMPORT_STRUC_CC, which will work without the explicit IMPORT - mapping.


 

Static field mapping

Sometimes, it is more convenient to have the mapping information directly in code instead of relying on customiziation.

The contents of the field name mapping - /EPO1/FIELD_MAP can also be defined in code, but the conversion ABAP <-> JSON has to be called manually (using the methods /EPO1/CL_TOOLS=>ABAP_TO_JSON or /EPO1/CL_TOOLS=>JSON_TO_ABAP).

 

further steps

Reduce JSON Output Data

Sometimes, an universal webservice will provide several completely different data structures (e.g. user data, invoice data, material data, ..).

This can be done by defining a large structure, which can hold each of the data to be delivered. However, the 'other' structure elements should not be returned.

Or, some 'initial' fields should be removed from the response (e.g. date fields, character strings, ..).


There are 2 implementations, wich are controlled by the response format in the service configuration table /EPO1/CONFIGOUT:

  • dynamically reduce the output structure (implicit, a transformation is used)
response format: 't', 'tb' or 'tbi'
  • strip the generation of JSON elements (implizit, the function module /EPO1/EXC_ABAP_TO_JSON is used)
response format: '0', '1', '2' or '10'


Please note, that the output of those both methods differ in some details (mapping of field names with '/', number- or date formatting).


Strip the output structure

Requirement: define one of the response formats: 't', 'tb' or 'tbi' Please note, that the stripping of output structures is limited to structures (und substructures); the inner content of a table cannot be stripped.


Define the export parameter ES_EPO1_ABAP_STRIP with the type /EPO1/EXC_ABAP_STRIP_STRUC. This structure contains all necessary parameters, which are used in the method /epo1/cl_tools=>abap_strip.

Meaning of the ABAP-STRIP - parameters:

  • IT_KEEP: list of elements, which should be kept
  • IT_STRIP: list of elements, which should be stripped (except, when listed in IT_KEEP)
  • IV_STRIP_INITIAL: if 'X', remove all empty elements (structures, tables, primitive elements)
  • IV_RECURSIVE: if 'X', recurse to all substructures
  • IV_STRIP_EVERYTHING: strip all elements, except when listed in IT_KEEP

Note 1: elements and sub-elements are to be written as in ABAP (e.g. ELEMENT-SUB_ELEMENT-SUB_SUB_ELEMENT-...)

Note 2: the upper most element is the generated element 'EXPORT' for export parameters, 'CHANGING' for changing parameters and 'TABLES' for tables parameters. For simplicity, we expect, that only export parameters are used in a webservice - function module.

Note 3: it is not possible to change the contents of a table; only structure element might be stripped.


Example - export parameters of the function module for the webservice:

USER_DATA     TYPE USR01
MATERIAL_DATA TYPE MARA
MESSAGES      TYPE BAPIRET2_T

remove everything except the user data:

es_epo1_abap_strip-iv_strip_everything = 'X'.
APPEND 'EXPORT-USER_DATA' TO es_epo1_strip-it_keep.

Note: usually, we know exactly, which data are to be returned, so this is the preferred way to strip output data. This will work even if the webservice is enhanced in the future by returning additional data.


remove all empty structures from export:

es_epo1_abap_strip-iv_strip_initial = 'X'.

Note: this is maybe the most universal setting; leaving only structure elements, which has been filled by


remove every empty element (recursive):

es_epo1_abap_strip-iv_strip_initial   = 'X'.
es_epo1_abap_strip-iv_strip_recursive = 'X'.

Note: this stripping might be useful, when very large structures are returned, where most of the elements are initial and does not need to be returned. So we can remove all of the unused data. If there are elements, which should be returned, even when initial - then simply add the names of these elements to the IT_KEEP list.


remove only the material data (complete structure):

APPEND 'EXPORT-MATERIAL_DATA' TO es_epo1_strip-it_strip.


remove only the material number from the material data (maybe useless.. just so show, how it works):

APPEND 'EXPORT-MATERIAL_DATA-MATNR' TO es_epo1_strip-it_strip.

 

Strip the generation of JSON elements

Requirements:

  • define one of the response formats: '0', '1', '2' or '10'
  • check the checkbox 'Field mapping (even, if there is no customizing for field name mapping)

For details, please refer the section /EPO1/JSON_STRIP


Use special parameters

There is a list of function module - parameters, which can be used to transport special information between the web interface and the function module. See page GFMC function module call for details.