This is a test message to test the length of the message box.
Login
ABAP Cloud HTTP Client
Created by Software-Heroes

ABAP Cloud - HTTP Client

534

What does the current HTTP client in ABAP Cloud look like? Let's take a look at the new model.



Access to HTTP endpoints will become more common with ABAP Cloud, especially if you want to call BTP services from your ABAP code. In this article, we'll look at the new released API and highlight its use in BTP and on-premise.

 

Introduction

The HTTP client has been a basic component of an SAP system for many years and if you search for the CL_HTTP_CLIENT class, you'll certainly find many examples of its use. However, interfaces have so far been built primarily with RFC, IDOC or SOAP, so the HTTP client has rarely been used. Meanwhile, using the old HTTP client also has some disadvantages:

  • Classic exceptions and how to handle them
  • No clear separation of client, request and response
  • Default values are not set properly (HTTP 1.0)

 

You can find an example of how it is used in one of our older articles.

 

Steampunk, Public Cloud

The successor is the class CL_WEB_HTTP_CLIENT_MANAGER in the system. This is available on-premise and in the cloud and can be used to access HTTP endpoints. In the following sections we will discuss creation and use.

 

Creation

Before we can call an endpoint, we must establish a connection. We can establish a connection using the CL_HTTP_DESTINATION_PROVIDER class. The class currently offers four methods for creation:

  • CREATE_BY_URL - Direct creation by specifying the URL. The method is very easy to use for testing purposes, but should later be replaced by a configuration (destination or arrangement).
  • CREATE_BY_COMM_ARRANGEMENT - Use of a communication arrangement. To do this, the system and the arrangement must be configured.
  • CREATE_BY_CLOUD_DESTINATION - Use a destination from the destination service in the BTP subaccount.
  • CREATE_BY_DESTINATION - Use an SM59 destination to create the object. In the documentation you will find the note that the method cannot be used in Steampunk.

 

In the example we create the connection via a URL:

DATA(lo_destination) = cl_http_destination_provider=>create_by_url(
    'https://software-heroes.com/api/v1/rest-test/partner' ).

 

We can get the request object using the GET_HTTP_REQUEST method. In this case, we want to set a header field and provide the API key of the interface:

lo_client->get_http_request( )->set_header_field( i_name  = 'Swh-API-Key'
                                                  i_value = c_api_key ).

 

Read

If we now want to read data, we first create a client and then execute the EXECUTE with the GET method. As a result, we receive an object with the result of the request:

DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).
DATA(lo_response) = lo_client->execute( i_method = if_web_http_client=>get ).

 

To get the contents of the request, we can use the various methods of the RESPONSE object.

DATA(ld_content_type) = lo_response->get_content_type( ).
DATA(ls_status) = lo_response->get_status( ).
DATA(ld_text) = lo_response->get_text( ).

 

If we look at the console, we get a corresponding response from the server:

 

Create

In this second example, we create a data record using a POST request via the API. In the first step, we create a new CLIENT, as in the previous example. Next, we get the request object and can add header fields or other properties to the request:

DATA(lo_request) = lo_client->get_http_request( ).
lo_request->set_header_field( i_name  = 'Swh-API-Key'
                              i_value = c_api_key ).

 

Now we configure the payload that we want to pass to the service. In this case, we simply generate the JSON directly in the code and pass it to the request.

lo_request->set_content_type( 'application/json' ).
lo_request->set_text( |{| &
                      |    "NAME": "VW",| &
                      |    "DESCRIPTION": "New cars",| &
                      |    "STATUS": "A",| &
                      |    "PRICE": 723.99,| &
                      |    "CURRENCY": "USD"| &
                      |}| ).

 

The execution now looks similar to reading, but we specify a different HTTP method. You can typically use POST to create a new data record with REST interfaces:

DATA(lo_response) = lo_client->execute( i_method = if_web_http_client=>post ).

 

More examples

You can find more examples in the SAP Community, SAP Help or on other blogs. Below we have linked an article in the SAP Community where you can find further details.

 

On-Premise, Private Cloud

In this section you will find information on use in an on-premise system.

 

Provider

The CL_WEB_HTTP_CLIENT_PROVIDER class is currently not available for the private cloud and on-premise. A destination can be created using the non-released class CL_OUTBOUND_PROVIDER_HTTP. The following methods are currently available for use:

  • CREATE_BY_DESTINATION - Use an SM59 destination to create the connection object.

 

Hint: In order to use the class in ABAP Cloud (TIER-1), you must write a TIER-2 wrapper. You can find further information on this in the document "ABAP Cloud API Enablement Guidelines" (point 2.3.1.3 - Connectivity).

 

Usage

First we have to create a connection again, this is currently only possible via a configured SM59 connection. In this example we use the original class, but for ABAP Cloud you need a wrapper.

" You need a wrapper for this class
DATA(lo_destination) = cl_outbound_provider_http=>create_by_destination( c_destination ).

 

Now we can implement the various options for calling the API and execute the request using EXECUTE.

DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).
DATA(lo_response) = lo_client->execute( i_method = if_web_http_client=>get ).

 

Planning

According to the plan, the S/4HANA 2025 release will include a successor API that can be used in all environments. We cannot yet say what the API will look like. Since this is a plan, you should use the wrapper for now.

 

Utility

The released API CL_WEB_HTTP_UTILITY is now available for the HTTP utility class CL_HTTP_UTILITY. If we look at the class, we quickly see that it is a wrapper for the old class. After all, the classic exceptions have been replaced by class-based exceptions and somewhat modernized. The class's range of functions includes:

 

  • UTF-8 conversion - This allows strings to be converted from UTF-8 to the internal format and in both directions.
  • BASE64 conversion - Here you can find the respective variants for string and XString.
  • URL functions - You can also find escaping, checking for correctness and normalizing URLs.

 

Hint: Not all of the functions of the original class are available and the class cannot be easily mocked in unit tests.

 

Complete example

Here you can find the complete code from the example shown. This currently only runs in the ABAP environment or the S/4HANA Public Cloud.

CLASS zcl_bs_demo_http_client DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

  PRIVATE SECTION.
    CONSTANTS c_api_key      TYPE string VALUE ``.
    CONSTANTS c_api_endpoint TYPE string VALUE `https://software-heroes.com/api/v1/rest-test/partner`.

    METHODS create_new_data
      IMPORTING i_out TYPE REF TO if_oo_adt_classrun_out.

    METHODS read_data
      IMPORTING i_out TYPE REF TO if_oo_adt_classrun_out.
ENDCLASS.


CLASS zcl_bs_demo_http_client IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
*    read_data( out ).
    create_new_data( out ).
  ENDMETHOD.


  METHOD read_data.
    TRY.
        DATA(lo_destination) = cl_http_destination_provider=>create_by_url( c_api_endpoint ).

        DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).

        lo_client->get_http_request( )->set_header_field( i_name  = 'Swh-API-Key'
                                                          i_value = c_api_key ).

        DATA(lo_response) = lo_client->execute( i_method = if_web_http_client=>get ).
        i_out->write( lo_response->get_content_type( ) ).
        i_out->write( lo_response->get_status( ) ).
        i_out->write( lo_response->get_text( ) ).

      CATCH cx_root INTO DATA(lo_error).
        i_out->write( lo_error->get_text( ) ).
    ENDTRY.
  ENDMETHOD.


  METHOD create_new_data.
    TRY.
        DATA(lo_destination) = cl_http_destination_provider=>create_by_url( c_api_endpoint ).

        DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).

        DATA(lo_request) = lo_client->get_http_request( ).
        lo_request->set_header_field( i_name  = 'Swh-API-Key'
                                      i_value = c_api_key ).

        lo_request->set_content_type( 'application/json' ).
        lo_request->set_text( |{| &
                              |    "NAME": "VW",| &
                              |    "DESCRIPTION": "New cars",| &
                              |    "STATUS": "A",| &
                              |    "PRICE": 723.99,| &
                              |    "CURRENCY": "USD"| &
                              |}| ).

        DATA(lo_response) = lo_client->execute( i_method = if_web_http_client=>post ).
        i_out->write( lo_response->get_content_type( ) ).
        i_out->write( lo_response->get_status( ) ).
        i_out->write( lo_response->get_text( ) ).

      CATCH cx_root INTO DATA(lo_error).
        i_out->write( lo_error->get_text( ) ).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

 

For on-premise and private cloud you can find the example with the non-released class here:

CLASS zcl_bs_demo_http_client DEFINITION
  PUBLIC FINAL
  CREATE PUBLIC.

  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

  PRIVATE SECTION.
    CONSTANTS c_destination TYPE rfcdest VALUE ''.
ENDCLASS.


CLASS zcl_bs_demo_http_client IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    TRY.
        " You need a wrapper for this class
        DATA(lo_destination) = cl_outbound_provider_http=>create_by_destination( c_destination ).

        DATA(lo_client) = cl_web_http_client_manager=>create_by_http_destination( lo_destination ).
        DATA(lo_response) = lo_client->execute( i_method = if_web_http_client=>get ).
        out->write( lo_response->get_content_type( ) ).
        out->write( lo_response->get_status( ) ).
        out->write( lo_response->get_text( ) ).

      CATCH cx_root INTO DATA(lo_error).
        out->write( lo_error->get_text( ) ).
    ENDTRY.
  ENDMETHOD.
ENDCLASS.

 

Conclusion

The situation with the HTTP client is not yet fully resolved and some rework is required to access the appropriate API, but the client can already be used. At least the utility class is already available in the system and can be used.

 

Further information:
SAP Community - ABAP & HTTP
SAP Community - Use New Client


Included topics:
ABAP CloudABAPHTTP Client
Comments (0)



And further ...

Are you satisfied with the content of the article? We post new content in the ABAP area every Friday and irregularly in all other areas. Take a look at our tools and apps, we provide them free of charge.


ABAP Cloud - Locks

Category - ABAP

What do you need to set locks for and how can you easily do that in ABAP Cloud? In this article we will look at the process in detail.

11/08/2024

ABAP Cloud - Key User Apps

Category - ABAP

Key User Extensibility is a part of ABAP Cloud when it comes to extending the core, but how can you use the tools effectively and how do they complement each other?

10/11/2024

ABAP Cloud - JSON Conversion

Category - ABAP

Is there a new API for converting JSON and do you need it for ABAP Cloud? Here we will take a look at the structure and conversion of JSON.

09/27/2024

ABAP Cloud - Number ranges

Category - ABAP

How can you use number ranges in ABAP Cloud and does this actually still make sense? In this article we will look at some of the background informations.

09/13/2024

ABAP Cloud - Data Types

Category - ABAP

What does it actually look like when using data elements in ABAP Cloud? In this article we look at alternatives in the definition.

09/06/2024