Skip to Content
User Experience Insights
Author's profile photo Matthew Billingham

Anti-pattern in RAP

A Rant

I’ve been working my way through the excellent opensap.com course, Building Apps with the ABAP RESTful Application Programming Model, when I came across the most egregious anti-pattern built into the very fabric of RAP.

(Fun fact, egregious used to mean really really good. Now it means really really excessively bad).

Week 5 is accessing an external OData service using a Custom Entity.

For some strange reason, parts were working fine until 6pm last night, when suddenly I started getting authentication errors… which were circumvented with the following code:

* https://blogs.sap.com/2019/10/20/how-to-call-a-remote-odata-service-from-the-trial-version-of-sap-cloud-* platform-abap-environment/
   http_client->get_http_request( )->set_authorization_basic(
        i_username = 'ES5 username'
        i_password = 'ES5 password'
    ).

I don’t know, perhaps “they” decided to switch on authentication. Anyway I digress.

What really ticked me off was that when I had finished the app, I discovered that if I didn’t include these calls in my implementation of IF_RAP_QUERY_PROVIDER~SELECT

    io_request->get_requested_elements( ).
    io_request->get_sort_elements( ).

I’d get a dump on the value help for agency ID.

I looked more closely at io_request concrete implementation, and found this:

  METHOD if_rap_query_request~get_sort_elements.
    ms_interface_methods_called-get_sort_elements = abap_true.
    rt_sort_elements = mt_sort_elements.
  ENDMETHOD.

  METHOD ensure_relevant_methods_called.
    TRY.
        IF ms_requested-fill_data = abap_true AND ms_interface_methods_called-get_sort_elements = abap_false AND mt_sort_elements IS NOT INITIAL.
          RAISE EXCEPTION cx_rap_query_not_fully_implmtd=>as_indicated_by_missing_call( co_interface_methods-get_sort_elements ).
        ENDIF.
...

So someone has decided that a GET method, which in any reasonable, rational universe should never have a side effect – if it’s not called, an exception will be raised.

Frankly, I’m morally shocked that such an antipattern has made it into an intrinsic part of RAP.

I’d love to hear the rationale…

 

 

 

 

 

 

 

 

Assigned Tags

      6 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Oleg Bashkatov
      Oleg Bashkatov

      there are additional opinion about rational universe and never side effect

      https://developer.mozilla.org/en-US/docs/Glossary/Idempotent

      Get methods are idempotent, but it does not mean that it has no side effect. and any good service has logs, statistics updation for workload analysis etc.

      As for RAP itself - we are all people... You could rise a ticket 🙂

      Author's profile photo Matthew Billingham
      Matthew Billingham
      Blog Post Author

      Undesirable side-effect then. The need to call these methods is entirely arbitrary. They don't do anything that's essential, except the programmer decided "they must be called". This leads to us developers encountering hard to resolve errors - unless you know the secret.

      Author's profile photo Lars Hvam
      Lars Hvam

      I wonder if the behavior could be changed via a ticket/fix? ABAP Cloud is promised to be backwards compatible, changing this behavior can be seen as a non-compatible change.

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Scratching my head here... I don't quite get where exactly the exception is happening. Are you saying get_requester_elements and get_sort_elements must be always called together or it's a no-go?

      The method name ensure_relevant_methods_called is a bit of a red flag... If something is required, just call the additional method yourself, no? I'm not 100% clear though on what exactly is the complaint...

      Also, by "side effect" did you mean the exception raised? I did a piece on "code like Google" recently and found it interesting that they recommend "no exceptions". I doubt this would work (or be practical) for SAP world but I've definitely seen some "you could've just handled this" exceptions.

       

       

      Author's profile photo Matthew Billingham
      Matthew Billingham
      Blog Post Author

      You must call the two methods before you return data to the front end:

         io_request->get_requested_elements( ).
         io_request->get_sort_elements( ).

      otherwise, during the response generation (in SAP's code), you get an exception

      Query not fully covered by implementation: Call to method if_rap_query_request~get_sort_elements missing

      thrown in /IWBEP/CL_MGW_LOCAL_HANDLER->GET_ENTITY_SET

      The side effect of the calls is to set a flag that the methods have been called.

      These are checked when the  response is being generated, to make sure they've been called. But you don't need to do anything with their returning parameter.

      It's just plain daft to insist a method is called when it clearly isn't needed. It's just arbitrary and leads to errors in our code that are hard to find if you don't know this secret piece of information.

       

       

      Author's profile photo Jelena Perfiljeva
      Jelena Perfiljeva

      Thanks for explanation! Yes, that seems pretty dumb... Sounds like a potential "improvement request", although I'm not quite sure where exactly those are supposed to go on the Influence website...