Custom header parameters in Gateway
I started off with GW learning as part of my new UI5 project .As you all know Gateway is a framework to expose the rich backend SAP data in the form of ODATA protocol.I am not going to give so many motherhood statements as it is well documented elsewhere
Now .. The Problem Statement
During so many scenarios, I came across a common requirement to pass some HTTP request header parameters .
To tell one sample scenario, there is an entity type Exemption .This entity type Exemption can be ‘Requested’ or ‘Approved’ from a business perspective from a UI application . The ‘Request’ or ‘Approve’ action can be done in batch for the Exemption record .If we model this as a property(I will call it the BusinessAction) in entity type Exemption, the problem is that the payload will have to repeat this property for all the records that it is sending. ๐ . All the more from a modelling perspective it does look silly to have BusinessAction in that entity type ๐
Then I came across a blog http://scn.sap.com/community/developer-center/netweaver-gateway/blog/2013/06/21/odata-custom-parameters–gateway-can-have-them-too from Ron Sargeant. This involved changes to both the GW Hub system layer and the backend BEP layer. In our case we did not have developer authorisation in GW hub system . The GW hub system is just used for registration of backend service..
So whats the option we have ??
Welcome Mr Trial & Error …
I just tried a sample scenario where in I send a sample HTTP request header parameter and see how does it reach our Broker GW and then ultimately to Uncle backends home..
I tired to send a Custom parameter via request header parameter for a sample Entity type.Now I put the break point in the our DPC class corresponding entity GET_ENTITYSET.The values
This part of debugging is called ‘Happy Debugging’
.I was happy to see the values appear in the importing parameter io_tech_request_context ๐
When I checked in debugger the io_tech_request_context is of type /IWBEP/CL_MGW_REQUEST with protected attribute MR_REQUEST
The attribute MR_REQUEST has deep structure TECHNICAL_REQUEST which has attributes like below and has a attribute REQUEST_HEADER
When we went inside we have the request header parameter that we set on the journey…
Now I thought its just a matter of reading the values .Its matter of reading values from io_tech_request_context->mr_request->request_header…(So simple)
This part of debugging is called ‘Not so happy Debugging’
I realised the attribute MR_REQUEST is a protected attribute and cannot be accessed by simple assignment to local variable. ๐ฅ
So Whats the workaround?
I made a subclass of the standard class /IWBEP/CL_MGW_REQUEST..
I wrote a method GET_REQUEST_HEADER_VALUE where in takes the request context object, header parameter and returns back the value
The code inside the method for reading the header parameter is as below
data:lo_request type ref to /IWBEP/IF_MGW_CORE_SRV_RUNTIME=>TY_S_MGW_REQUEST_CONTEXT,
lt_request_headers TYPE tihttpnvp,
ls_request_header like LINE OF lt_request_headers.
lo_request = io_tech_request_context->mr_request.
lt_request_headers = lo_request->technical_request–request_header.
READ TABLE lt_request_headers into ls_request_header with key name = iv_request_parameter.
if sy–subrc eq 0.
rv_request_value = ls_request_header–value .
endif.
Reading the value
Now I just need to use the utility method GET_REQUEST_HEADER_VALUE of subclass to get the custom parameter value.
Use the following code in your CRUDQ method to read the request header
DATA: lo_tech_request TYPE REF TO /iwbep/cl_mgw_request,
lo_tech_request_sub TYPE REF TO zcl_gw_mgw_request,
lt_headers TYPE tihttpnvp,
lv_request_header type string,
lv_request_header_value type string.
**Casting and Assigning importing parameter to local variable
lo_tech_request ?= io_tech_request_context.
***Instantialte subclass with some dumy header parameters
CREATE OBJECT lo_tech_request_sub
EXPORTING
it_headers = lt_headers..
lv_request_header_value = lo_tech_request_sub->get_request_header_value( EXPORTING io_tech_request_context = lo_tech_request
iv_request_parameter = ‘customparameter‘ ).
Testing the code -Final showdown..
Now in GW client in the GW hub system I run the below URL with HTTP header request custom parameters
Now in the debugger of GET_ENTITYSET…
will try this when i get the requirement.
Thanks Vishnu...
There is no need to use a custom subclass in Gateway 2.0 SP09 (not sure about other Support Packs) when using the following code in your DPC_EXT class:
DATA: lo_facade TYPE REF TO /iwbep/if_mgw_dp_int_facade,
lt_request_headers TYPE tihttpnvp,
ls_request_headers LIKE LINE OF lt_request_headers.
* Read the HTTP Request headers.
lo_facade ?= /iwbep/if_mgw_conv_srv_runtime~get_dp_facade( ).
lt_request_headers = lo_facade->get_request_header( ).
Regards,
JB
one-liner that works -
ME->MR_REQUEST_DETAILS->TECHNICAL_REQUEST-REQUEST_HEADER
Thanks Jonathan. This really helps.
Hello Arshad,
Again a absolutely awesome blog posted.
Its fun to see how you dramatize the learning process.. ๐ ๐ esp. the lines:
This part of debugging is called 'Happy Debugging'
Keep up the good work.
Thanks for share !
Best Regards,
PavanG
Hi ,
for some reason any custom headers that i add in the request do not reach the back-end, I'll looking at the same place as u in the debugger.
I'm unable to find out where it is that they are getting removed.
Would you know anything about this behavior .
Thanks
Amarpreet.
Hi,
I am also facing the same issue.
Do you have any solution?
Thanks
Rajdeep
Hi All,
I have solved this by passing parameter in slug.
It reached to the backend.
Thanks,
Rajdeep
Hi All,
I seem to getting a similar issue. I am passing headers to my oModel via setHeaders in UI. But I cannot even see the headers in my request headers in the Network Tab.
Any idea what could be the issue?
Thanks,
Amita
Hi ,
I am also facing the same issue.
Do you have any solution?
Thanks,
Rajdeep
Isย there any possiblity to send language as HTTP Request Parameter ?
I tried with the below options:
Accept-Languageย - DE
CustomParameter - DE
Please suggest.
Regards,
Lokeswar.