cancel
Showing results for 
Search instead for 
Did you mean: 

How to enable caching for SAP OData V2?

CyrusDaguro
Explorer
0 Kudos
75
  • SAP Managed Tags:

Hello SAP experts!

May I enquire on how can I register my OData service for caching?

I referred to these guides by SAP and I was able to add my service in transaction code /UI2/CACHE.

After that, I'm kind of lost by SAP's guides:

Cache for OData Services | SAP Help Portal

Registering an OData Service for Caching | SAP Help Portal

My situation:
I tried creating an OData V2 for table MARA to discover its capabilities using the service implementation below. I noticed that every time I do client-paging ($top and $skip), data repeatedly gets queried from HANA database for every request/page which makes it inefficient.

My plan:

I thought maybe there's a way to (1) cache the queried data and do the client-paging from there. And (2) after sending to the requestor all pages of data, cache can now be emptied.

Steps I've done so far:

1) implement the OData for MARA with full and delta capabilities, dynamic select and dynamic where clauses.

 

 

METHOD mara_get_entityset.

* =================================================================================================
*   Description :     Fetch MARA data based on filter and selection criteria.
*   Author      :     
*   Date        :     
*
*   Parameters:
*      it_filter_select_options     : Table containing filter criteria
*      iv_filter_string             : Dynamic filter string for SQL WHERE clause
*      io_tech_request_context      : Context providing technical request details
*      et_entityset                 : Output table containing the result set
*      es_response_context          : Structure for response metadata
*
*   Purpose:
*      This method extracts data from the MARA table based on provided
*      filters from the OData URL. It handles both full and delta loads,
*      processes $top and $skip parameters for pagination, and supports
*      dynamic field selection through $select queries.
* =================================================================================================


* =================================================================================================
*   Prepare variables
* =================================================================================================
  "Declare
  DATA:
    lv_select                     TYPE string,
    lt_mara                       TYPE STANDARD TABLE OF mara.

  "Initialize
  CLEAR:
    lv_select,
    lt_mara[],
    et_entityset[].


* =================================================================================================
*   Retrieve $filter values
* =================================================================================================
  "Scan all filters from request
  LOOP AT it_filter_select_options ASSIGNING FIELD-SYMBOL(<lfs_f_so>).

    "Check if LOAD filter is present
    IF <lfs_f_so>-property = 'LOAD'.

      "Read the first selection only of LOAD filter
      READ TABLE <lfs_f_so>-select_options ASSIGNING FIELD-SYMBOL(<lfs_so>) INDEX 1.

        "Check if LOAD filter is 'DELTA'
        IF to_upper( <lfs_so>-low ) = 'DELTA'.
          DATA(lv_load) = to_upper( <lfs_so>-low ).
          EXIT.
        ENDIF.

    ENDIF.

  ENDLOOP.


* =================================================================================================
*   Retrieve $select values
* =================================================================================================
  "Scan all selected fields from request
  DATA(lt_select) = io_tech_request_context->get_select( ).

  "Build dynamic select string
  LOOP AT lt_select ASSIGNING FIELD-SYMBOL(<lfs_select>).

    IF <lfs_select> IS INITIAL.
      lv_select = <lfs_select>.
    ELSE.
      lv_select = |{ lv_select }, { <lfs_select> }|.
    ENDIF.

  ENDLOOP.

  "Set dynamic select to select ALL
  IF lv_select IS INITIAL.
    lv_select = '*'.
  ENDIF.


* =================================================================================================
*   Query data from database
* =================================================================================================
  "Execute delta load
  IF lv_load = 'DELTA'.

    DATA(lv_yesterday) = sy-datum - 1.

    "Extract data from yesterday to future
    SELECT (lv_select)
      FROM mara
      INTO TABLE lt_mara
      WHERE ( ersda >= lv_yesterday AND laeda = '00000000' )
        OR ( laeda >= lv_yesterday AND laeda <> '00000000' )
      ORDER BY matnr ASCENDING.

  "Execute full load
  ELSE.

    IF iv_filter_string IS NOT INITIAL.

      "Query data using $filter
      SELECT (lv_select)
        FROM mara
        INTO TABLE lt_mara
        WHERE (iv_filter_string)
        ORDER BY matnr ASCENDING.

    ELSE.

      "Query all data
      SELECT (lv_select)
        FROM mara
        INTO TABLE lt_mara
        ORDER BY matnr ASCENDING.

    ENDIF.

  ENDIF.

  "Get row count
  DATA(lv_count) = sy-dbcnt.


* =================================================================================================
*   Prepare data for integration
* =================================================================================================
  "Check if the query returned data
  IF lt_mara IS NOT INITIAL.

    "Check if request has $count
    IF io_tech_request_context->has_count( ) = abap_true.

      "Respond with row count of dataset
      es_response_context-count = lv_count.

    ELSE.

      "Retrieve $top and $skip query options
      DATA(lv_top) = io_tech_request_context->get_top( ).
      DATA(lv_skip) = io_tech_request_context->get_skip( ).

      "Check if paging is included in request
      IF lv_top IS NOT INITIAL OR lv_skip IS NOT INITIAL.

        DATA(lv_end_index) = lv_skip + lv_top.

        "Set ending index to row count to prevent out-of-bounds issue
        IF lv_end_index > lv_count.
          lv_end_index = lv_count.
        ENDIF.

        "Respond with paginated dataset
        LOOP AT lt_mara FROM lv_skip + 1 TO lv_end_index ASSIGNING FIELD-SYMBOL(<ls_mara>).
          APPEND CORRESPONDING #( <ls_mara> ) TO et_entityset.
        ENDLOOP.

        "Release memory occupied
        FREE:
          lv_top,
          lv_skip,
          lv_end_index.

      ELSE.

        "Respond with whole dataset
        et_entityset = CORRESPONDING #( lt_mara ).

      ENDIF.

    ENDIF.

    "Release memory occupied
    FREE:
      lv_load,
      lv_select,
      lv_count,
      lt_mara[].

  ENDIF.

ENDMETHOD.

 

2) add the service of MARA OData to /UI2/CACHE

CyrusDaguro_0-1738741692083.png

Couple notes:
1) Im using the OData to send data to Azure/Databricks Lakehouse

2) We are only using SAP ECC on HANA with runtime license so my options with integration are limited.

 

Hope you can help me with cache-ing thank you!

 

 

Accepted Solutions (0)

Answers (0)