EPO Consulting Wiki - EPO Connector - GFMC function module call


The EPO GFMC (Generic Function Module Call) exposes any SAP function module as web service either with XML or JSON formatted data.

Beside some required customizing, we will show how this works - and how to use very special function module parameters.

Processing steps

SAP services are customized in transaction SICF. An example is the service path /default_host/epo1soa/jsonapphandler with the handler class /EPO1/JSONHANDLER. This SICF handler accepts requests in JSON format and returns responses in JSON. For XML, use the handler class /EPO1/XMLHANDLER, like used in /default_host/epo1soa/xmlhandler

According to the EPO customizing, the correct function module name will be selected according to the given (called) combination of EPO service and EPO operation.

When called, a dynamic function module handler - report will be generated (when necessary) - and invokes the function module. This dynamically generated report will be re-created, if the called function module has been changed since the last generation. So the call will usually be very fast.


How to write a function module

The function module to be called should preferrably use only 'importing' and 'exporting' parameters; try to avoid 'changing' and 'tables', as they are not well suited to map the usage of a usual web service call. Do not raise exceptions, but return meaningful error messages to the user.

Maybe, it might be useful to write a wrapper function module to an existing function module, which handles all errors and returns error messages in case of errors.


Parameter mapping

The request (=incoming data) is a structure with the main elements 'IMPORT', 'CHANGING' and 'TABLES'.

The response (=outgoing data) is a structure with the main elements 'EXPORT', 'CHANGING' and 'TABLES'.

Each main element has (structured or primitive) child-elements according to the defined parameters of each category. There are a few exceptions for special EPO - parameters, which are neither mapped to the request nor to the response ( see below for details ).


Parameter example

Suppose a function module with

  • importing parameters:
  • IV_STRING of type string
  • IV_INT of type integer
  • IS_STRUC of type /EPO1/EXC_PARAMETER (with an element 'NAME' and another element 'VALUE')
  • exporting parameters:
  • EV_STRING of type string
  • EV_INT of type integer
  • ET_STRING of type /EPO1/EC_STRING_TABLE (which is a table with strings)


The JSON request should look like:

{
  "IMPORT": {
    "IV_STRING":"some string",
	"IV_INT":5,
	"IS_STRUC": {
	  "NAME":"some_name",
	  "VALUE":"some_value"
	}
  }
}

The JSON response would look like:

{
  "EXPORT": {
    "EV_STRING":"some result",
	"EV_INT":42,
	"ET_STRING": [
	  "string_one",
	  "string_two",
	  "last_string"
	]
  }
}


Please note, that only those request - elements are passed to the function modules, which have matching input/changing/tables parameters.

Special EPO - parameters

Some special named parameters are not mapped to request/response, but are used to pass special data to/from the called function module. These parameters are truely optional, so it is not neccessary to specify them (except, You want to use them!).


Import parameter IT_EPO1_REQUEST_HEADERS

..of type TIHTTPNVP is used to pass the HTTP headers of the request into the function module.


Export parameter ES_EPO1_ABAP_STRIP

..of type /EPO1/EXC_ABAP_STRIP_STRUC. This very special parameter can be used to dynamically strip some elements out of the response structure.

Suppose a REST webservice, which is able to return some very different kind of data:

  • material data
  • user data
  • error message(s)
  • ..

All these data has to be supplied in the EXPORT parameters of the function module. However, only a part of the response is filled, depending on the usage of the function module.

With the parameter /EPO1/EXC_ABAP_STRIP_STRUC, the function module is able to control, which data is to be removed from the response. See the detailed description, how to use these parameters.

Export parameter EV_EPO1_HTTP_CODE

..of type I; the function module may set the HTTP code in order to signal success or failure - states, without returning any data.


Export parameter EV_EPO1_HTTP_REASON

..of type STRING; here, the function moduly might supply the descriptive text to the HTTP code.

Note: by default, the GFMC-framework will supply the HTTP reason by default from the EV_EPO1_HTTP_CODE, using the mapping of the interface IF_HTTP_STATUS. So it is usually NOT necessary to use and fill this parameter.

Export parameter ET_EPO1_RESPONSE_HEADERS

..of type TIHTTPNVP is used to pass the HTTP headers to the response.  

Field name mapping

In order to support JSON field names other than the uppercase-variant of the ABAP field names, a name mapping can be switched-on in the EPO customizing of the operation:

ClipCapIt-200825-093039.PNG

Select 'Field Mapping' and the response format 't' (with transformation - not supported in old releases) or '0' (using a function module to create the JSON response).

The conversion schema has to be customized - see the description of table /EPO1/FIELD_MAP for details.  

avoid the IMPORT / EXPORT structures

As described above, the request has to contain the main structure 'IMPORT', while the response contains the main structure 'EXPORT'. To get rid of those main structures, specify following transformations in the EPO customizing of the operation:

ClipCapIt-200825-094051.PNG

The transformation /EPO1/EXC_JSON_IMPORT_STRUC will generate an IMPORT-structure as wrapper over all input parameters.

The transformation /EPO1/EXC_JSON_EXPORT_STRUC will remove the EXPORT-structure and leave all child elements as root-elements of the response. The removal of the EXPORT-structure happens after the field name mapping. Our transformation handles lower-case and camel-case mappings. Only, if the name of the EXPORT-element has been mapped to a very different name, You would need to write a special transformation for that case.

Compare the now valid JSON structurs against the original ones (above) - examples without field name mapping.

The JSON request should now look like:

{
	"IV_STRING":"some string",
	"IV_INT":5,
	"IS_STRUC": {
		"NAME":"some_name",
		"VALUE":"some_value"
	}
}

The JSON response would now look like:

{
	"EV_STRING":"some result",
	"EV_INT":42,
	"ET_STRING": [
		"string_one",
		"string_two",
		"last_string"
	]
}