Many of us remember the ABAP dynpro programming model as the methodology to create user interfaces on top of business applications in a lot of SAP products. Furthermore, SAP GUI is still a widely used technology.
ABAP dynpro is tightly integrated with the ABAP Dictionary: the definition of domains, data elements, structures, and database tables influences the appearance of, the behavior of, and the content representation in an ABAP dynpro user interface.
Take domains, for example. Domains may reference conversion exits. These exits define a transformation between the representation in the ABAP runtime environment and the representation on the UI.
Let us take a look at the so-called alpha conversion routine (not to be confused with alpha conversion in lambda calculus):
The five-character conversion exit identification ALPHA is added to a character-like domain,
VBELN in this case. As a result, for any purely numerical content of a corresponding field leading zeros are omitted during output on UI but added to numerical user input. Any non-numerical content stays as it is in both directions.
The left screenshot shows the representation of a sales document number (based on domain
VBELN) in the famous transaction VA03 while the right screenshot displays the same sales document in SE16, that is, the representation in database table
The transformation from the ABAP representation (with leading zeros in our example) to the representation on the UI is called outbound conversion while the other direction is called inbound conversion.
Please observe that these conversion exits have nothing to do with locale-dependent representations of dates, times, or amounts. Nevertheless, conversion exits may also take the logon language into account.
Technically, conversion exits are implemented as function modules that follow a certain naming convention:
CONVERSION_EXIT_<exitID>_OUTPUT. Their signature contains an importing parameter
INPUT and an exporting parameter
OUTPUT without type specification.
OData and SAP Gateway Foundation
Nowadays, SAP Fiori is the user experience paradigm. Its technological basis relies on SAPUI5 with OData as the protocol for data transfer between backend and UI client. SAP Gateway Foundation enables the usage of OData. In case of a typical ABAP backend SAP Gateway Foundation is the framework that allows you to develop, to expose, and to administer OData services.
When using SAP Gateway Foundation to create an OData service on top of an existing ABAP business application it can be assumed that conversion exits are taken into account as described above.
And yes, the framework provides features to automatically execute conversions such that the OData service exposes data in a way that is comparable to the former representation in SAP GUI.
But since OData defines a type system that is different from the type system in the ABAP runtime environment things get a little complicated. The conversion feature in SAP Gateway Foundation is very powerful and supports much more than just the conversion exits mentioned above.
In a small series of blog posts let us explore the secrets of conversions in SAP Gateway Foundation both for OData version 2.0 and OData version 4.0. We start with the above example of conversion exits in the context of OData version 2.0.
Starting Point – An Example
Let us stick to the sales document number. Suppose you want to create an OData service that provides sales document headers using a direct access to the database.
Your OData service will define an entity type,
SD_HEADER for example. And, there will be an entity set
SD_HEADER_SET. For the sake of simplicity we assume that the ABAP names are used in the OData metadata document.
The entity type
SD_HEADER will get a key property
VBELN to identify the sales document header through the sales document number.
If we would just expose the database content in the OData service a (JSON) response would look like this:
How do we achieve that the system automatically applies the ALPHA conversion as defined in the ABAP Dictionary such that the OData service returns the following result?
The answer is simple: we provide the dictionary information to SAP Gateway Foundation. The mechanism to do this is called binding.
Option 1 – Structure Binding
After having created the entity type (storing the object in
lo_entity_type) with its properties you implement the following call in the
DEFINE method of the model provider class:
lo_entity_type->bind_structure( iv_structure_name = 'VBAK' iv_bind_conversions = abap_true ).
Please observe the importing parameter
IV_BIND_CONVERSIONS. If it would not be set to
ABAP_TRUE then SAP Gateway Foundation would take over type information from the ABAP Dictionary but would not take the conversion information into account.
This code is also generated if you use transaction SEGW (SAP Gateway Service Builder) to build your service. In this design time tool you would just specify the name of the ABAP Dictionary structure when defining the entity type:
The generator will create the above method call with
IV_BIND_CONVERSIONS = ABAP_TRUE automatically.
Option 2 – Element Binding
Similarly, if you create your properties independent of a structure and you just want to use ABAP Dictionary information for a single property you can call method
BIND_DATA_ELEMENT at the respective property object (
lo_property, for example) providing the name of a data element. Again, do not forget to set
lo_property->bind_element( iv_element_name = 'DATA_ELEMENT_NAME' iv_bind_conversions = abap_true ).
IV_BIND_CONVERSIONS has been added to this method in SAP_GWFND 740 SP13 and higher. Hence, earlier releases do not support this function. You either need to use structure binding or the following feature.
Independent of any ABAP Dictionary reference you are able to specify a conversion exit at the property using method
SET_CONVERSION_EXIT. The method expects the 5-character identification of the conversion exit as it would have been entered in the domain.
lo_property->set_conversion_exit( 'ALPHA' ).
Be careful, the method does not check the existence of the conversion exit. It just adds the information to the property which implies that the method may also be used to override a conversion exit that has previously been determined using structure binding.
The last sentence may sound as if the method could also be used to remove a conversion exit. In principle, this is possible if an initial value is provided to the method.
A more appropriate way is the usage of method
/IWBEP/IF_MGW_ODATA_PROPERTY~DISABLE_CONVERSION at the property class. It does not remove the conversion information from the property object but switches off its usage.
lo_entity_type = model->get_entity_type( 'SD_HEADER' ). lo_entity_type->get_property( 'Vbeln' )->disable_conversion( ).
There is a corresponding method
ENABLE_CONVERSION. But this method cannot be used to derive conversion exit information from the ABAP Dictionary retroactively. It just resets the switch that has been set with
Another switch that allows to disable conversions is the method
/IWBEP/IF_MGW_ODATA_MODEL~SET_NO_CONVERSION at the model itself. It disables all conversions for the complete model – we will discuss in subsequent blog posts why this is not advisable at all. Consider that you cannot re-enable a conversion for a property using
ENABLE_CONVERSION if the conversion has been switched off for the complete model.
To summarize, the best way to work with the conversions is as follows: use structure binding with
IV_BIND_CONVERSIONS = ABAP_TRUE and disable conversions at the individual property if needed.
Now, if a (primitive) property of an OData service “knows” about an assigned conversion exit SAP Gateway Foundation may execute an inbound conversion for content of a request payload and filter expressions or key predicates in the request URI. Outbound conversions are processed for the response payload.
In the next blog post we are going to discuss a bit more theoretical and technical background about how SAP Gateway Foundation transfers and serializes data, and when and where conversions are executed.