3

Conversion Exits and the ABAP RESTful Application Programming Model (RAP)

 1 year ago
source link: https://blogs.sap.com/2022/06/27/conversion-exits-and-the-abap-restful-application-programming-model-rap/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
June 27, 2022 6 minute read

Conversion Exits and the ABAP RESTful Application Programming Model (RAP)

Motivation

Problem Statement

You may have encountered a message like “You cannot use the XYZ conversion exit here” when trying to publish an OData V2 or V4 service via RAP service binding. The reason is that most conversion exist are not allowed any more in the context of OData services as they lead to various issues. This blog explains the reasoning behind.

Remark: The issues apply in general while only for RAP Service Binding and currently only in S/4HANA there is a strict check preventing to publish such a service to avoid undetected issues from the beginning.

Stateful vs. Stateless Communication

In general conversion exits are an artifact of the SAPGUI world, while partially also used for purposes other than defining the display format of a field value. In the classical ABAP world you work on a restricted set of data on the application server and on this data certain operations are invoked. Let’s take a simple example of an ALV list where generic features like sorting, filtering, aggregating etc. pp. work on the provided data set. On this data set also conversion exits are executed and operations like sorting or filtering are invoked on the converted values. This works as the data set is limited.

In the stateless world of OData services and S/4HANA we are working on the full (usually huge) data set by leveraging the HANA database delegating data-intense logic down to HANA. Thus in this case filtering and sorting is done on the database and can only work on persisted data (or data calculated on database level – which is not a good idea, see below).

Issues with Conversion Exits

Based on the use cases and concrete conversion exist various issues exist and here are some of these.

Technical Issues

Data Type Violations

Technically the output of a conversion exit is a string / character-like data type. If the type changes, this cannot be reflected in the domain or the conversion exit itself, so often this is an issue in the OData exposure as the resulting value violates the OData Edm data type.

Example: There are many conversion exits on timestamps that convert the timestamp to a readable date and time for the UI. This definitely will violate the Edm.DateTimeOffset and in fact such a conversion is completely unnecessary as the semantics of the data is provided via different means and the UI can render the same in a proper and readable way. In this case the semantics is already defined via the Edm data type, in other cases there may be semantics annotations.

Complex Filter Conditions

Filters on fields with conversion exit that provide also a RANGE_INPUT conversion function module often lead to too complex or too large filter conditions that violate or exceed the valid length of the resulting WHERE condition (or leads to extremely bad performance of the SQL statement).

Functional Issues

SEARCH

Search (in app search as well as enterprise search) does not work at all as the search term looks for hits in many different fields and thus a conversion to the search term cannot be done.

Example: An internal ID “1234567890” is converted to an external ID “MY ID” shown to the user. searching with “MY ID” won’t find anything which obviously does not meet the user expectation.

FILTER

Filters do only work sometimes. For “equals” filters usually the conversion is applied, but for patterns and ranges this is only applied if the conversion exist also provides a RANGE_INPUT function module (which is only present for some conversion exist and might also not work for all cases).
Sort does only work if the sort order is not changed by the conversion. For many conversions this is not guaranteed. Further sort is a pre-condition for proper paging which is essential when working with entities with large data sets.

Data exposure via other channels (e.g. Data Extraction)

Data extraction on database level (e.g. via  CDS extraction views) does not work as internal unconverted data is extracted. Thus (as the knowledge is not known “outside”) this data cannot be related to data read e.g. via an OData channel or essential information like external IDs or their representation is missing.

Draft Handling

Basic idea of the draft concept is that data can be stored incomplete or inconsistent. This does not work with conversion exits in many cases as some conversion exits even raise exceptions and often data types of external and internal representation have a different length or have even incompatible data types so that also storing the entered data is not possible and thus violates the draft concept.

Solution

Allowed Conversion Exits

Certain conversion exists are on the allow list, mainly the very central ones where it is known what the functionality behind is (allowing to judge the issues mentioned above). Mainly these are:

  • ALPHA
    • changes the sort order by definition
    • is fully respected / supported by filter and search
    • does not change the data type and length but jut adds / removes leading zeros for numeric IDs
  • ISOLA (for language code)
    • filtering / sorting supported via range conversion, only simple filters relevant
    • search not applicable / reasonable
  • CUNIT (for unit of measure)
    • filtering / sorting supported via range conversion, only simple filters relevant
    • search not applicable / reasonable

Further SAP has introduced some technical conversion exists due to the S/4HANA Amount Field Length Extension (AFLE), but these are removed in the OData exposure as here the proper data type length is reflected in the OData metadata already.

Unnecessary Conversion Exits

Conversion exits (like the time stamp example above) that are just not needed and applicable in OData services may just be removed. As usually in other channels like SAPGUI transactions these are still needed the removal cannot be done on domain level, but you may cast in your CDS model to a data element without conversion exit.

Remark: In most cases for SAP-defined conversion exits you will find an appropriate data element already.

ID or Code Conversions (persisted converted values)

The majority of conversion exits converts an internal value (ID or Code) to an external value (sometimes also to the related text).

In many cases the converted value is also persisted on the database. In this cases the proper external value or text should be modeled accordingly and exposed (only or in addition to the internal representation depending on the needs). So the related fields should be associated or joined from the proper data source.

In the transactional world these fields should also be enabled in the transactional model for editing to ensure data input is not lost (especially in the draft case) even if the conversion is not possible (due to a wrong input value). The conversion (or better the determination of the internal finally to be persisted value) is then done within the application logic.

Conversion Exits for Input Validations

Some conversions are only used for input validations. These should not be used at all as they also violate the draft concept. Validations should properly be done in the application layer (also to achieve a harmonized and reasonable user experience). While ideally in case of errors all issues are returned to the client in case a conversion would fail already only this single error is reported back.

Remark: In the UI with Fiori / Fiori Elements you may even already validate certain values on the client, e.g. for codes by using a drop down box instead of free input field.

Other Conversion Exits (not persisted converted values)

As the variety of conversion exist is very high, there is no silver bullet to solve them all. In general removing the obviously critical conversion exits leading to technical errors and the ones where the converted value is already present on the database as such, for the remaining ones a case by case  solution needs to found.

If the data is really essential there is barely no other way as to persist the converted value to meet the user expectation to e.g. be able to search for IDs as these are shown on the UI or to also provide the data to other consumers like data extraction or analytics.

Remark: It is definitely not a good idea (if technically feasible at all) to move the conversion logic down to HANA into a CDS calculated field or even an AMDP or CDS Table Function. In most cases this would lead to a full materialization of the affected column in case an operation like sorting or filtering on this column is invoked. This will lead to bad performance or even timeouts based on the underlying data sets.

Summary

Conversion exits are not bad and a great feature in the classical ABAP world, but as seen do not really fit into the stateless RESTful world of RAP and S/4HANA and the HANA push down. The good thing is that for most cases there is a straight forward solution in place by either just removing the conversion exit if not needed casting to an appropriate data element or by adding the field with the converted value to the data model. Only in special cases a different solution is required that might lead to more effort to be fixed.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK