본문 바로가기
ABAP/개발Tip

[개발Tip] RESTful API 호출 2가지 방법(CL_HTTP_CLIENT, CL_REST_HTTP_CLIENT)

by name_text 2023. 6. 28.

CL_HTTP_CLIENT

CL_REST_HTTP_CLIENT

 

SAP에서 외부 RESTful API를 호출하여 JSON 데이터를 받는 2가지 방법입니다.

GET/POST/PUT/DELETE 와 같이 RESTful 에서 사용하는 HTTP Method 모두 사용 가능하며 최대한 간단하게 예시 소스코드를 작성했습니다.

참고로 CL_REST_HTTP_CLIENT는 내부적으로 CL_HTTP_CLIENT를 호출하는 방식입니다.

 

POST와 GET의 경우에는 HTTP_POST, HTT_GET 펑션을 이용해도 동일한 결과를 얻을 수 있습니다.

 

# CL_HTTP_CLIENT 예시

PARAMETERS: P_URL TYPE STRING LOWER CASE,              "URL
            P_DEST TYPE RFCDISPLAY-RFCDEST LOWER CASE, "RFC 목적지
            P_AUTH TYPE STRING LOWER CASE,             "Authorization
            P_METHOD TYPE STRING OBLIGATORY,           "HTTP METHOD
            P_JSON TYPE STRING LOWER CASE.             "Request Body JSON

DATA: LO_HTTP_CLIENT TYPE REF TO IF_HTTP_CLIENT.
DATA: LO_EXCEPTION   TYPE REF TO CX_ROOT.
DATA: LV_STATUS_CODE  TYPE  I,
      LV_STATUS_TEXT  TYPE  STRING.

DATA: LT_RESPONSE_HEADER TYPE TIHTTPNVP.

* #1. HTTP Client
  IF P_URL IS NOT INITIAL.
    "URL로 직접 호출
    CALL METHOD CL_HTTP_CLIENT=>CREATE_BY_URL
      EXPORTING
        URL                    = P_URL
      IMPORTING
        CLIENT                 = LO_HTTP_CLIENT
      EXCEPTIONS
        ARGUMENT_NOT_FOUND     = 1
        PLUGIN_NOT_ACTIVE      = 2
        INTERNAL_ERROR         = 3
        PSE_NOT_FOUND          = 4
        PSE_NOT_DISTRIB        = 5
        PSE_ERRORS             = 6
        others                 = 7
            .
  ELSEIF P_DEST IS NOT INITIAL.
    "RFC 목적지로 호출
    CALL METHOD CL_HTTP_CLIENT=>CREATE_BY_DESTINATION
      EXPORTING
        DESTINATION              = P_DEST
      IMPORTING
        CLIENT                   = LO_HTTP_CLIENT
      EXCEPTIONS
        ARGUMENT_NOT_FOUND       = 1
        DESTINATION_NOT_FOUND    = 2
        DESTINATION_NO_AUTHORITY = 3
        PLUGIN_NOT_ACTIVE        = 4
        INTERNAL_ERROR           = 5
        others                   = 6
            .
  ELSE.
    EXIT.
  ENDIF.
  IF SY-SUBRC <> 0.
    LV_STATUS_CODE = 500.
    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4 INTO LV_STATUS_TEXT.
    WRITE:/ LV_STATUS_CODE, LV_STATUS_TEXT.
    EXIT.
  ENDIF.

* #2. Request 생성
  "HTTP METHOD 설정
  LO_HTTP_CLIENT->REQUEST->SET_METHOD( P_METHOD ).
  "Content type 설정 (application/json)
  LO_HTTP_CLIENT->REQUEST->SET_CONTENT_TYPE( IF_REST_MEDIA_TYPE=>GC_APPL_JSON ).
  "Accept type 설정 (application/json)
  LO_HTTP_CLIENT->REQUEST->SET_HEADER_FIELD( NAME  = 'Accept' VALUE = IF_REST_MEDIA_TYPE=>GC_APPL_JSON ).
  "Authorization 설정
  IF P_AUTH IS NOT INITIAL.
    LO_HTTP_CLIENT->REQUEST->SET_HEADER_FIELD( NAME  = 'Authorization' VALUE = P_AUTH ).
  ENDIF.
  "Request Body
  IF P_JSON IS NOT INITIAL.
    LO_HTTP_CLIENT->REQUEST->SET_CDATA( P_JSON ).
  ENDIF.

* #3. HTTP Call
  TRY.
    LO_HTTP_CLIENT->SEND( ).
    LO_HTTP_CLIENT->RECEIVE(
      EXCEPTIONS
        HTTP_COMMUNICATION_FAILURE = 1
        HTTP_INVALID_STATE         = 2
        HTTP_PROCESSING_FAILED     = 3
        OTHERS                     = 4 ).
    IF SY-SUBRC <> 0.
      LV_STATUS_CODE = 500.
      MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4 INTO LV_STATUS_TEXT.
      WRITE:/ LV_STATUS_CODE, LV_STATUS_TEXT.
      EXIT.
    ENDIF.
  CATCH CX_ROOT INTO LO_EXCEPTION.
    LV_STATUS_CODE = 500.
    LV_STATUS_TEXT = LO_EXCEPTION->GET_TEXT( ).
    WRITE:/ LV_STATUS_CODE, LV_STATUS_TEXT.
    EXIT.
  ENDTRY.

* #4. Response
  "Response Body JSON
  DATA(LV_RESPONSE_JSON) = LO_HTTP_CLIENT->RESPONSE->GET_CDATA( ).
  "Response Body Content-type
  DATA(LV_RESPONSE_CTYPE) = LO_HTTP_CLIENT->RESPONSE->GET_CONTENT_TYPE( ).
  "Response Content Length
  LO_HTTP_CLIENT->RESPONSE->IF_HTTP_ENTITY~GET_DATA_LENGTH( IMPORTING DATA_LENGTH = DATA(LV_RESPONSE_LENGTH) ).
  "Status code, Status text
  LO_HTTP_CLIENT->RESPONSE->GET_STATUS( IMPORTING CODE    = LV_STATUS_CODE
                                                  REASON  = LV_STATUS_TEXT ).
  "Response Headers
  LO_HTTP_CLIENT->RESPONSE->GET_HEADER_FIELDS( CHANGING FIELDS = LT_RESPONSE_HEADER ).
  "HTTP Close
  LO_HTTP_CLIENT->CLOSE( ).

  WRITE:/ LV_STATUS_CODE, LV_STATUS_TEXT.
  WRITE:/ LV_RESPONSE_CTYPE, LV_RESPONSE_LENGTH.
  WRITE:/ LV_RESPONSE_JSON.
  EXIT.
ABAP

 

# CL_REST_HTTP_CLIENT

PARAMETERS: P_URL TYPE STRING LOWER CASE,              "URL
            P_DEST TYPE RFCDISPLAY-RFCDEST LOWER CASE, "RFC 목적지
            P_AUTH TYPE STRING LOWER CASE,             "Authorization
            P_METHOD TYPE STRING OBLIGATORY,           "HTTP METHOD
            P_JSON TYPE STRING LOWER CASE.             "Request Body JSON

DATA: LO_HTTP_CLIENT TYPE REF TO IF_HTTP_CLIENT,
      LO_REST_CLIENT TYPE REF TO CL_REST_HTTP_CLIENT,
      LO_REQUEST     TYPE REF TO IF_REST_ENTITY,
      LO_RESPONSE    TYPE REF TO IF_REST_ENTITY.
DATA: LO_EXCEPTION   TYPE REF TO CX_ROOT.
DATA: LV_STATUS_CODE  TYPE  I,
      LV_STATUS_TEXT  TYPE  STRING.

DATA: LT_RESPONSE_HEADER TYPE TIHTTPNVP.

* #1. HTTP Client
  IF P_URL IS NOT INITIAL.
    "URL로 직접 호출
    CALL METHOD CL_HTTP_CLIENT=>CREATE_BY_URL
      EXPORTING
        URL                    = P_URL
      IMPORTING
        CLIENT                 = LO_HTTP_CLIENT
      EXCEPTIONS
        ARGUMENT_NOT_FOUND     = 1
        PLUGIN_NOT_ACTIVE      = 2
        INTERNAL_ERROR         = 3
        PSE_NOT_FOUND          = 4
        PSE_NOT_DISTRIB        = 5
        PSE_ERRORS             = 6
        others                 = 7
            .
  ELSEIF P_DEST IS NOT INITIAL.
    "RFC 목적지로 호출
    CALL METHOD CL_HTTP_CLIENT=>CREATE_BY_DESTINATION
      EXPORTING
        DESTINATION              = P_DEST
      IMPORTING
        CLIENT                   = LO_HTTP_CLIENT
      EXCEPTIONS
        ARGUMENT_NOT_FOUND       = 1
        DESTINATION_NOT_FOUND    = 2
        DESTINATION_NO_AUTHORITY = 3
        PLUGIN_NOT_ACTIVE        = 4
        INTERNAL_ERROR           = 5
        others                   = 6
            .
  ELSE.
    EXIT.
  ENDIF.
  IF SY-SUBRC <> 0.
    LV_STATUS_CODE = 500.
    MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4 INTO LV_STATUS_TEXT.
    WRITE:/ LV_STATUS_CODE, LV_STATUS_TEXT.
    EXIT.
  ENDIF.

* #1. REST Client 생성
  TRY.
    CREATE OBJECT LO_REST_CLIENT
      EXPORTING
        IO_HTTP_CLIENT = LO_HTTP_CLIENT.
  CATCH CX_ROOT INTO LO_EXCEPTION.
    LV_STATUS_CODE = 500.
    LV_STATUS_TEXT = LO_EXCEPTION->GET_TEXT( ).
    WRITE:/ LV_STATUS_CODE, LV_STATUS_TEXT.
    EXIT.
  ENDTRY.

  IF LO_HTTP_CLIENT IS NOT BOUND OR LO_REST_CLIENT IS NOT BOUND.
    EXIT.
  ENDIF.

* #2. Request 생성
  LO_REQUEST = LO_REST_CLIENT->IF_REST_CLIENT~CREATE_REQUEST_ENTITY( ).
  "Content type 설정 (application/json)
  LO_REQUEST->SET_CONTENT_TYPE( IV_MEDIA_TYPE = IF_REST_MEDIA_TYPE=>GC_APPL_JSON ).   "content-type : application/json

  "Accept type 설정 (application/json)
  LO_REST_CLIENT->IF_REST_CLIENT~SET_REQUEST_HEADER( IV_NAME  = 'Accept' IV_VALUE = IF_REST_MEDIA_TYPE=>GC_APPL_JSON ).
  "Authorization 설정
  IF P_AUTH IS NOT INITIAL.
    LO_REST_CLIENT->IF_REST_CLIENT~SET_REQUEST_HEADER( IV_NAME  = 'Authorization' IV_VALUE = P_AUTH ).
  ENDIF.
  "Request Body
  IF P_JSON IS NOT INITIAL.
    LO_REQUEST->SET_STRING_DATA( P_JSON ).
  ENDIF.

* #3. HTTP Call
  TRY.
    CASE P_METHOD.
      WHEN 'POST'.
        LO_REST_CLIENT->IF_REST_RESOURCE~POST( LO_REQUEST ).
      WHEN 'PUT'.
        LO_REST_CLIENT->IF_REST_RESOURCE~PUT( LO_REQUEST ).
      WHEN 'GET'.
        LO_REST_CLIENT->IF_REST_RESOURCE~GET( ).
      WHEN 'DELETE'.
        LO_REST_CLIENT->IF_REST_RESOURCE~DELETE( ).
    ENDCASE.
  CATCH CX_ROOT INTO LO_EXCEPTION.
    LV_STATUS_CODE = 500.
    LV_STATUS_TEXT = LO_EXCEPTION->GET_TEXT( ).
    WRITE:/ LV_STATUS_CODE, LV_STATUS_TEXT.
    EXIT.
  ENDTRY.

* #4. Response
  LO_RESPONSE = LO_REST_CLIENT->IF_REST_CLIENT~GET_RESPONSE_ENTITY( ).
  "Response Body JSON
  DATA(LV_RESPONSE_JSON) = LO_RESPONSE->GET_STRING_DATA( ).
  "Response Body Content-type
  LO_RESPONSE->GET_CONTENT_TYPE( IMPORTING EV_MEDIA_TYPE = DATA(LV_RESPONSE_CTYPE) ).
  "Response Content Length
  DATA(LV_RESPONSE_LENGTH) = LO_RESPONSE->GET_CONTENT_LENGTH( ).
  "Status code, Status text
  LV_STATUS_CODE = LO_REST_CLIENT->IF_REST_CLIENT~GET_STATUS(  ).
  LV_STATUS_TEXT = LO_RESPONSE->GET_HEADER_FIELD( '~status_reason' ).
  "Response Headers
  LT_RESPONSE_HEADER = LO_RESPONSE->GET_HEADER_FIELDS( ).
  "HTTP Close
  LO_HTTP_CLIENT->CLOSE( ).

  WRITE:/ LV_STATUS_CODE, LV_STATUS_TEXT.
  WRITE:/ LV_RESPONSE_CTYPE, LV_RESPONSE_LENGTH.
  WRITE:/ LV_RESPONSE_JSON.
  EXIT.
ABAP

댓글