Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Call API on Presentation Server using CL_HTTP_CLIENT

miguel_motta
Participant
0 Kudos
748

Hi,

Is there the possibility of consuming an API exposed on my local machine (Presentation Server) using the CL_HTTP_CLIENT class (or another method if it exists)?
SAP is accessed using SAP Gui, and the connection can be made with SAP Router or not. Due to this, there is a possibility that my machine is not on the same network that Application Server, which I imagine rules out the possibility of direct access via IP.
The exposed API communicates with local devices (USB), which makes it impossible for the API to be placed on a server.
Each user will access SAP from their own machine, and the API will be exposed on each of them.

Regards,
Miguel Motta

13 REPLIES 13

Sandra_Rossi
Active Contributor
739

EDIT: I didn't test what I proposed, so it was just a guess. See the comment by @Ulrich_Schmidt below about the restriction of CL_HTTP_CLIENT=>CREATE_BY_DESTINATION to work only with RFC destinations of type G/H.

Via CL_HTTP_CLIENT, if you use the RFC connection "SAPHTTP", it will access the Web through the HTTP interface on the user's laptop (through the SAP GUI "saphttp" program), as opposed to "SAPHTTPA" which corresponds to the HTTP interface on the ABAP server.

RFC connection "SAPHTTP" (SM59):

Sandra_Rossi_1-1718799769686.png

SAPHTTPA:

Sandra_Rossi_2-1718799888475.png

 

0 Kudos
700

Thanks Rossi!

I hadn't thought about this possibility.

I have already used these RFCs with the HTTP_GET and HTTP_POST functions, but never with the CL_HTTP_CLIENT class.
I was a little confused on how I can create the object pointing to the SAPHTTP RFC (create_by_destination?) and set the API service URL.
Can you help me?

0 Kudos
667

create_by_destination

EDIT about indicating an exact URL via create_by_destination (you may find the answer in the forum too): the URL given in the RFC destination is only the root URL (so it can be empty = domain root), you may append any URL to it via either cl_http_utility=>SET_REQUEST_URI or set_header_field of pseudo header field ~request_uri.

Ulrich_Schmidt
Product and Topic Expert
Product and Topic Expert
572

I just checked with the developer: destination SAPHTTP can not be used with CL_HTTP_CLIENT. One needs to access it via CALL FUNCTION to certain function modules.

Ulrich_Schmidt
Product and Topic Expert
Product and Topic Expert
606

Can destination SAPHTTP be accessed via CL_HTTP_CLIENT? I always thought, CL_HTTP_CLIENT communicates through HTTP-destinations of type G and H, but SAPHTTP is an RFC-destination (type T), which needs to be accessed via CALL FUNCTION. (The RFC call transfers the URL and other parameters to the saphttp.exe executable, which then makes the HTTP request.)

0 Kudos
514

Good point, I didn't test. Answer edited.

thomas_mller13
Participant
0 Kudos
613

CL_HTTP_CLIENT is a HTTP client. If you want to consume an API on the client computer via CL_HTTP_CLIENT you need a webserver there which is accessing the API.  

Ulrich_Schmidt
Product and Topic Expert
Product and Topic Expert
586

(or another method if it exists)?

Another option might be the following: as you are accessing a hardware connected to an USB slot, you have probably written a C/C++ component that accesses the USB device via the driver provided by the hardware vendor?

In that case, why not call the C/C++ component directly from ABAP (without detour via HTTP Client & HTTP Server on the frontend)? This is actually not so difficult. Basic outline:

  1. Create an SM59 destination of type T with "start on frontend", similar to how the SAPHTTP destination looks like, but instead of "saphttp.exe" you enter your own executable name.
  2. Put the functionality, which access the USB device driver, into an executable and link it with the NW RFC Library (sapnwrfc.dll).
  3. In order to be invocable from ABAP, that executable needs to fulfill two prerequisites:
    - From main(), it needs to call the function RfcStartServer(), passing in the command line parameters it receives when being started. (SAPGUI will start the executable as a child process, passing in the details necessary for connecting to the current ABAP user session.)
    - It needs to define and implement the interface of one (or more) remote-enabled function module.
    The details for this are described in the NW RFC SDK Programming Guide, chapter 5 (in particular section 5.3), which can be downloaded from https://support.sap.com/nwrfcsdk
    The interface would define the inputs that the USB device needs and the outputs returned by the USB device. Can be simple strings, ints or floats, or even tables or binary blobs.

Then you would need to install that executable on the end-user frontends, for example together with the device driver DLL (which is needed in any case), and then your ABAP program on the Application Server can access the end-user's USB device with a simple

 

DATA: error_detail(120).

CALL FUNCTION 'MY_FUNCTION' DESTINATION 'DEST_FROM_STEP1'
  EXPORTING
    "...inputs needed by USB device
  IMPORTING
    "...results from USB device
  TABLES
    "...if any
  EXCEPTIONS
    SYSTEM_FAILURE = 1 MESSAGE error_detail
    COMMUNICATION_FAILURE = 2 MESSAGE error_detail.

IF sy-subrc EQ 1.
  "e.g. USB device not plugged in etc.
ELSEIF sy-subrc EQ 2.
  "network connection between app server and frontend broke down
ENDIF.

 

 

0 Kudos
579

What happens if you run that call several times in parallel?

0 Kudos
572

That depends on your executable: every locking/synchronization that the USB device might need, needs to be implemented in the executable (e.g. using OS level semaphores etc.).

But I think it is very hard to run the call several times in parallel from within the same user session (SAPGUI session). You would need to use the ABAP parallelization mechanism via "STARTING NEW TASK" etc.

0 Kudos
527

Such tasks are typically done in batch. In this case collisions happen very often. The question is: what happens if 2 or more RFC clients use the same destination? Even if they start a new instance of server program.

0 Kudos
488

In this articular scenario, the calls are made only from an end-user session (logged on life with SAPGUI). So there should be no collision possible here: if two end-users log on at the same time, one instance of the executable will be started on notebook A and the other one on notebook B, and they should not interfere.

(Only possibility is, if the same user opens two SAPGUI sessions on his notebook/desktop, and starts a call in both of them. And if this is a problem for the USB device, then what I said in the previous post applies: the executable needs to use an operating system level semaphore to protect the USB device against simultaneous access from two processes. The RFC protocol does not have any such protection mechanism and will happily execute both calls in parallel.)

0 Kudos
529

Hi Schmidt,

Accessing the service via calls to DLL functions is an option and I will analyze whether it is the best way. The DLLs already exist and perhaps this is the shortest way.
Alternatively, I can use the HTTP_POST function with the SAPHTTP RFC, since all API services in question work with the POST method. In this case, I will only need to configure SSL.


I am very grateful for the attention and clarifications of all my colleagues.

Best regards