Skip to Content

Since starting with Gateway I’ve always wondered why one of the simplest OData conventions is not implemented in Gateway yet.

Simply stated, at the end of a resource path you can add typical query string parameters that you would see in other URI schemes -makes sense.

e.g.  <resource_path>/<resource_endpoint>?sap-language=EN

If you call a service with this kind of URI scheme, it won’t object. Nor will it pass those parameters to your backend provider.

From previous REST developments in SAP, I knew that the query string was probably being accepted and even present, so why was it lost?

After a debugging session that would have benefited from 3D googles, I found the answer.

a) Gateway uses the query string for other “stuff”.

b) If that other stuff, such as $expand is present, then it gets processed.

c) If what is in the query string is not within an elite group of parameters, it is unceremoniously discarded.

I thought this was rather harsh – they are only trying to be helpful. Time to be helpful in return.

I want my parameters. I planned them, raised them and sent them off on a journey and I want to see them arrive safely at Uncle Backend’s home. Uncle Backend will put them to good use and probably keep me in his will.

Now I know the following is probably going to dislodge a very firm stick from a very tight posterior socket somewhere, but I decided to do something about it.

“Get your custom parameters here!”

The first step was to enhance the ODATA processor, namely class /IWFND/CL_SODATA_PROCESSOR, Method INIT_REQUEST. If you have separate GW and BEP, this class will be in the GW instance.

This was done with the following implicit enhancement on the post-exit.

/wp-content/uploads/2013/06/postexit_234547.png

The basic story here is that the exported table ‘et_parameter’ is responsible for persisting the parameter name-value pairs through the request cycle.

It is at this point that all will be lost if we cannot grab them – this piece of code does that. Anything that was in the query string is saved.

How do you access them in the backend? Well, they aren’t exposed in the CRUD method signatures, but they are present in the provider runtime object – you just need to know where to find them.

Or write a method in the data provider to read them – like this:

/wp-content/uploads/2013/06/method_234560.png

It is then just a case of calling this method with a parameter name to see if it is present and get its value.

/wp-content/uploads/2013/06/call_234561.png

Rather than write this method into every DPC class, I’d suggest putting into an interim custom class inserted into the class inheritance if possible. That way it will appear in all your DPC’s. It’s easy to do in SP03 but a bit harder in SP04 using SEGW-generated code, I suspect.

I have used this enhancement with no ill effects on a live project and both SP03 and SP04 versions, but anyone wishing to use this solution does so at their own risk.

Regards

RS

To report this post you need to login first.

10 Comments

You must be Logged on to comment or reply to a post.

  1. Andre Fischer

    Hi Ron,

    this is a very useful blog. There are certainly many scenarios where one would like to retrieve custom query parameters in addition to the OData query parameters.

    However using the parameter sap-language as an example is in my opinion a little bit problematic because it should not be used in productive applications.

    Reason is that the language of the logged on user is taken from the HTTP Accept-Language header by the framework.

    Using the parameter sap-language might lead to unwanted results if you integrate a HTML based application into another Web page.

    While the Web page will show results based on the HTTP Accept-Language header (for example in English) only the HTML5 based app would show results in Spanish.

    The parameter is however a great help for developers that want to test their applications in different languages because changing the logon language this way is much faster than changing the default language of your browser.

    Best Regards,

    Andre

    (0) 
    1. Ron Sargeant Post author

      Hi Andre,

      I agree that ‘sap-language’ is not a great example, but it was the first thing that came to mind and the example is more about query parameters in a URI scheme. You will however find ‘sap-client’ in the parameters, for example, which is added by the ICM I presume. In fact, the omission of sap-language in the parameters was the one thing we found annoying as we had no idea of the client language, nor could we find any standard means of determining this from the client request.

      The workaround for this was to add language as a filter but that was not pretty as a filter element needs to be an entity property – not something that is always wanted.

      We did actually implement this for a language parameter, but as you will see in the last code example, it is called ‘language’ in our actual usage.

      Cheers

      Ron.

      (0) 
      1. Ralf Handl

        Hi Ron,

        What was your use case for selecting the language? And how often would the language be switched per “session”?

        Thanks in advance!
        –Ralf

        (0) 
        1. Ron Sargeant Post author

          Hi Ralf,

          In this case, I am not 100% familiar with the use case as the project I was working with just wanted a means of specifying language and a custom parameter was one way of doing it.

          However, it was a customer self-service solution with customers across Europe logging into a non-SAP web host which then obtained its feeds from SAP CRM and ERP via Gateway.

          When talking about ‘session’ I assume you mean the user web session (service request sessions are stateless so I cannot see how a “language switch” would apply there) in which case I cannot answer as I never saw the UI running (this is becoming more common in Gateway projects). I’ll assume the browser locale was used to determine language for service calls, but there may have been an option to alter language in the application space.

          Regards

          Ron.

          (0) 
  2. Graham Robinson

    Thanks for this Ron.

    I found in later versions other parameters ( like $filter ) started to pop up. To prevent parameter duplication I modified your enhancement slightly.

    ENHANCEMENT ZGW_ODATA_CPARM.    “active version

    *Retrieve all parameters from the Query String  and add to et_parameters

    DATA: lt_zz_params TYPE tihttpnvp,      

          lr_zz_params TYPE REF TO ihttpnvp,

          lr_zz_params_out TYPE REF TO/IWCOR/IF_ODATA_TYPES=>parameter_values_s.


      mo_context->get_parameter(

        exporting iv_name = ‘IWFND/QUERY_PARAMETERS’

        importing ev_value = lt_zz_params ).  


      LOOP AT lt_zz_params REFERENCE INTO lr_zz_params.   

        READ TABLE et_parameter

         WITH KEY name = lr_zz_params->name

         TRANSPORTING NO FIELDS.  

        CHECK sy-subrc NE 0.

        APPEND INITIAL LINE TO et_parameter

         REFERENCE INTO lr_zz_params_out.

        lr_zz_params_out->name = lr_zz_params->name.

        lr_zz_params_out->value = lr_zz_params->value. 

      ENDLOOP.


    ENDENHANCEMENT.

    Cheers

    Graham Robbo

    (0) 
  3. Ralf Handl

    Hi Ron,

    Custom query options have one severe drawback: there’s no way to describe them, their syntax, and their applicability in $metadata. Which means that you need out-of-band communication for telling clients where and how to use your custom query option. No chance for generic clients to use them.

    So in most cases where custom behavior is needed this can be done with a function import returning whatever you need and taking declared parameters controlling the result.

    We use custom query options for generally applicable concepts that are not (yet) in the OData standard, e.g. the custom query option search=, see SAP Annotations for OData Version 2.0. Which by the way made into OData 4.0 as a system query option $search=, see OData Version 4.0 Part 1: Protocol.

    Hope this explains the intentionally missing support for custom query options

    Regards!

    –Ralf

    (0) 
    1. Ron Sargeant Post author

      Hi Ralf,

      I’ve been aware of the ‘hidden’ nature of custom parameters for some time and to be fair, I don’t really use them anyway. As they were in the spec, I wanted to see if they could be implemented. It looks like they are now deprecated in OData 4.0?

      I’m a big fan of comprehensible services, unfortunately a quick scan of the Gateway development threads reveals that the majority of services being developed are “internal” and quite incomprehensible as they are using Gateway for all manner of weird scenarios.

      (hang on, that’s what SAP do with UI2 as well 😕 )

      For the usual reasons (lack of time / interest / intelligence 😉 ), a lot developers don’t think in big picture mode – as long as it works “here and now”, they consider it job done (or their boss does, more importantly).

      Regards

      Ron.  

      (0) 

Leave a Reply