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
'ABAP > 개발Tip' 카테고리의 다른 글
[개발Tip] Event 호출로 백그라운드 작업 실행(Event Batch) (0) | 2023.09.14 |
---|---|
[개발Tip] ALV Field catalog(필드 카탈로그) 만드는 3가지 방법 (0) | 2023.08.25 |
[개발Tip] REPLACE의 REGEX (정규표현식)를 이용한 특수문자 제거 (0) | 2023.06.22 |
[개발Tip] 비동기 처리를 위한 백그라운드 작업 생성 (0) | 2023.06.22 |
[개발Tip] Internal Table 성능(Select into, Read, Loop where) 비교 (1) | 2023.05.16 |
댓글