Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
Former Member

How do we consume XS services (hosted on a different domain) in our SAP UI5 application (hosted on gateway server)? Generally it shouldn't have been a problem, but as UI5 apps are usually run on chrome all UI5 developers would or will have faced the dreaded CORS ! issue at some time while consuming an XS service.

CORS (Cross-Origin-Resource-Sharing), to explain in brief a web security measure to ensure that services that reside outside our domain can only be used if there is a trust between them (like an SSL connection). This creates a small roadblock as UI5 developers try to consume XS services. Let's say hosted on http://xs.engine.com while the UI5 app resides on gateway let's say hosted at http://gateway.com, as the Gateway domain and XS aren't the same we get the dreadful CORS error. Don't get me wrong, CORS has probably saved a lot of enterprise sites from being hacked so it quite necessary for web security

Moving on, for this blog I will be describing how to consume only XSJS service in Gateway and not XSODATA services.

There are three possible solutions to solve this

1. Use a proxy over XS engine so that the Gateway can make a secure connection to consume the services.

2. Use JSONP data type to consume XSJS while making an ajax call from SAPUI5

3. Create an ABAP object (RFC preferably) in Gateway that will consume the XSJS service and publish the data using an ICF service (created on the Gateway)

I have performed both solution 2 and 3. I will be describing solution 2 in another blog. Although using JSONP is way more easier than solution 3 there are a few drawbacks which will be explained in the next blog:


How to consume XSJS as JSONP in SAPUI5 application.

For Step 1 and 2 i referred a very useful blog by Amaresh Pani : http://scn.sap.com/community/abap/connectivity/blog/2014/11/09/calling-an-external-restful-service-f...

Note the XSJS service here is a GET service. I will be exploring this more in the next few days for POST services as well.

The service I am trying to hit is : http://<XS engine host>:<port>/JohanXSJS/XSJS/Profit_Center.xsjs?comp=XXXX

Step 1: Create an RFC destination with connection type G (i.e. to External Server) to your XS engine

You can mention the DB user credentials in the Logon tab that would ensure that you that you can access the XSJS service without a logon prompt.

Step 2: Create an RFC to use this RFC destination and call any XSJS service dynamically.


FUNCTION z_xsjs_get_data.


*"----------------------------------------------------------------------


*"*"Local Interface:


*"  IMPORTING


*"     VALUE(IV_URL) TYPE  STRING


*"  EXPORTING


*"     VALUE(JSON_STRING) TYPE  STRING


*"----------------------------------------------------------------------



   DATA : lo_http_client TYPE REF TO if_http_client,


          lo_rest_client TYPE REF TO cl_rest_http_client,


          lo_response    TYPE REF TO if_rest_entity,


          lv_url         TYPE        string.



   cl_http_client=>create_by_destination(


    EXPORTING


      destination              = 'HANAXS'    " Logical destination (specified in RFC destination above)


    IMPORTING


      client                   = lo_http_client    " HTTP Client Abstraction


    EXCEPTIONS


      argument_not_found       = 1


      destination_not_found    = 2


      destination_no_authority = 3


      plugin_not_active        = 4


      internal_error           = 5


      OTHERS                   = 6


  ).



   CREATE OBJECT lo_rest_client


     EXPORTING


       io_http_client = lo_http_client.



   cl_http_utility=>set_request_uri(


    EXPORTING


      request = lo_http_client->request    " HTTP Framework (iHTTP) HTTP Request


      uri     = iv_url                     " URI String (in the Form of /path?query-string)


  ).



   lo_rest_client->if_rest_client~get( ).



   lo_response = lo_rest_client->if_rest_client~get_response_entity( ).



   json_string = lo_response->get_string_data( ).



ENDFUNCTION.





Step 3: Make a handler class that will be consumed by ICF service node

     Add an interface as shown below to the class to make a Handler class for ICF service

This provides the below method definition:

This method definition given by this interface will provide the necessary parameters. Write the below code in that method :


METHOD if_http_extension~handle_request.



     DATA : lv_string TYPE string,


            lv_url    TYPE string.



     lv_url = '/JohanXSJS/XSJS/Profit_Center.xsjs?comp=XXXX'.



     CALL FUNCTION 'Z_XSJS_GET_DATA'


       EXPORTING


         iv_url      = lv_url


       IMPORTING


         json_string = lv_string.



     CALL METHOD server->response->set_cdata( data = lv_string ).


   ENDMETHOD.





Step 4: Make an ICF service that will call the above RFC.


Go to  transaction SICF and select the below hierarchy :

Click on the Create Host/Service button at the top left corner to create a new node under this hierarchy.


In the Handler tab enter the name of the class you've created in Step 3 :

Right click on the node then Activate this node and then test it in the browser.


Now this service will be as follows : http://<gateway host>:<port>/sap/bc/zxsjs?sap-client=XXX.


You can add query parameters that can be captured in your handler class. I will be updating the blog with how to call two or more services with this one handler class.


In your UI5 code you can access this service with an ajax call to this service. Hope this helps all the UI5 developers out there !!

2 Comments
Labels in this area