Post

Synchronizing SAP Tables with RFC or Web Services

Synchronizing SAP Tables with RFC or Web Services

When integrating SAP systems with external services or managing data between SAP landscapes, reading tables programmatically is often a key task. The function module RFC_READ_TABLE and its RESTful counterpart are reliable solutions for this. In this post, we’ll explore both methods, highlight their strengths and limitations, and walk through code examples to illustrate how to use them cleanly and effectively.


🧠 Understanding RFC_READ_TABLE

RFC_READ_TABLE is a widely-used remote-enabled function module that allows non-SAP systems to read data from SAP tables securely, using the Remote Function Call (RFC) protocol.

🔧 Key Highlights

  • ✅ Remote read access to SAP application tables
  • ✅ Safe alternative to direct DB queries
  • ✅ Highly flexible with filtering and field selection
  • ❗ Limited to one table at a time
  • ❗ Max row length: 512 characters on older systems
  • ❗ Cannot transfer fields with floating point values

Used properly, RFC_READ_TABLE can be a powerful bridge between your SAP backend and external systems.

🧾 RFC_READ_TABLE: ABAP Example

Here’s a modern and clean ABAP implementation using RFC_READ_TABLE. This snippet demonstrates how to read a table remotely, split its contents, and map it to a local internal table dynamically:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
DATA: lv_msg TYPE char255.

DATA: lr_table TYPE REF TO data,
      lr_line  TYPE REF TO data.

DATA: lt_data TYPE sdti_result_tab.

FIELD-SYMBOLS: <t_table> TYPE STANDARD TABLE.

CALL FUNCTION 'RFC_READ_TABLE'
  DESTINATION iv_rfc_destination
  EXPORTING
    query_table           = iv_tabname
    delimiter             = '|'     " Unicode pipe to avoid clashes
    use_et_data_4_return  = abap_true
  IMPORTING
    et_data               = lt_data
  EXCEPTIONS
    table_not_available   = 1
    table_without_data    = 2
    option_not_valid      = 3
    field_not_valid       = 4
    not_authorized        = 5
    data_buffer_exceeded  = 6
    system_failure        = 7 MESSAGE lv_msg
    communication_failure = 8 MESSAGE lv_msg
    OTHERS                = 9.

IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
    WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.

CREATE DATA lr_table TYPE TABLE OF (iv_tabname).
ASSIGN lr_table->* TO <t_table>.

CREATE DATA lr_line TYPE (iv_tabname).
ASSIGN lr_line->* TO FIELD-SYMBOL(<s_line>).

LOOP AT lt_data ASSIGNING FIELD-SYMBOL(<s_data>).
  CLEAR <s_line>.
  SPLIT <s_data>-line AT '|' INTO TABLE DATA(lt_fields).

  LOOP AT lt_fields ASSIGNING FIELD-SYMBOL(<f_field_remote>).
    ASSIGN COMPONENT sy-tabix OF STRUCTURE <s_line> TO FIELD-SYMBOL(<f_field_local>).
    ASSERT sy-subrc EQ 0.
    <f_field_local> = <f_field_remote>.
  ENDLOOP.

  APPEND <s_line> TO <t_table>.
ENDLOOP.

MODIFY (iv_tabname) FROM TABLE <t_table>.

✅ This implementation is reusable, dynamic, and ensures type safety using field symbols and runtime type creation.


🌐 RFC_READ_TABLE via RESTful API

For more modern architectures (especially cloud integrations or microservices), exposing SAP functionality via RESTful APIs is highly desirable. You can wrap RFC_READ_TABLE using a custom SAP Gateway service or a REST handler like the restful implementation.

Here’s a simplified pseudo-code example in ABAP:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
DATA: lv_msg      TYPE char255.

DATA: lr_table TYPE REF TO data,
      lr_line  TYPE REF TO data.

FIELD-SYMBOLS: <t_table> TYPE STANDARD TABLE,
               <s_line>  TYPE any.

" Create HTTP client
cl_http_client=>create_by_url(
  EXPORTING
    url                = |{ iv_endpoint }{ iv_tabname }?sap-client=100&format=JSON|
  IMPORTING
    client             = DATA(lo_http_client)
  EXCEPTIONS
    argument_not_found = 1
    plugin_not_active  = 2
    internal_error     = 3
    others             = 4
).
IF sy-subrc NE 0.
  lv_msg = 'Could not create HTTP client'.
  MESSAGE lv_msg TYPE 'E'.
ENDIF.

" Send GET request
lo_http_client->send( ).
lo_http_client->receive( ).

IF lo_http_client->response->get_status( ) NE '200'.
  lv_msg = lo_http_client->response->get_status_text( ).
  MESSAGE lv_msg TYPE 'E'.
ENDIF.

" Read response body
DATA(lv_json) = lo_http_client->response->get_cdata( ).

" Create dynamic internal table from table name
CREATE DATA lr_table TYPE TABLE OF (iv_tabname).
ASSIGN lr_table->* TO <t_table>.

CREATE DATA lr_line TYPE (iv_tabname).
ASSIGN lr_line->* TO <s_line>.

" Deserialize JSON into internal table
CALL METHOD /ui2/cl_json=>deserialize
  EXPORTING
    json        = lv_json
  CHANGING
    data        = <t_table>
  EXCEPTIONS
    others      = 1.

IF sy-subrc <> 0.
  MESSAGE 'JSON deserialization failed' TYPE 'E'.
ENDIF.

MODIFY (iv_tabname) FROM TABLE <t_table>.

🛡️ Ensure the REST layer handles:

  • Authentication (Basic, OAuth2, or JWT)
  • Query parameter sanitization
  • Proper error messaging and response formatting

💡 Synchronization Strategy Tips

When using either method for system synchronization, consider:

  • 🧱 Pagination: Use rowcount and rowskips to handle large data sets.
  • 🔒 Security: Avoid exposing sensitive tables via open APIs.
  • 🧹 Field Filtering: Only select necessary columns.
  • 📊 Incremental Syncs: Use LAST_CHANGED_AT or ERDAT fields to sync deltas.
  • 🕰 Retry Logic: Build resilience into your integration layer.

🧠 Final Thoughts

Whether you’re working with legacy systems or building next-gen microservices, extracting SAP data with RFC_READ_TABLE - or its RESTful variant - is a cornerstone of enterprise integration. The ABAP-based approach offers power and flexibility within SAP environments, while the REST API route caters to modern development practices and simplifies cross-platform communication.

Choose the approach that best suits your infrastructure, wrap it with good coding practices, and always keep performance, security, and scalability in mind.

This post is licensed under CC BY 4.0 by the author.