(클라우드) ABAP를 사용하여 REST API를 소비합니다
후 방법 호출
REST API로 작업 할 때 SAP는 응용 프로그램 간의 통신에 REST API를 사용합니다. 이 기사에서는 특히 Cloud ABAP 기능을 사용하여 ABAP를 사용하여 REST API를 소비하는 방법을 살펴 봅니다. 알아야 할 핵심 사항은 다음과 같습니다
- API는 응용 프로그램 프로그래밍 인터페이스를 나타냅니다. 두 개의 응용 프로그램이 서로 통신 할 수 있습니다.
- REST API는 HTTP 프로토콜을 사용하여 API를 구축하고 URI를 통해 JSON 또는 XML 데이터를 보내거나 수신하는 패턴입니다.
- SAP 세계에서 인기있는 Odata는 REST API의 유형입니다.
- ABAP에서 외부 API 소비, 특히 클라우드 ABAP 용 화이트리스트 API 소비에 대한 정보가 제한되어 있습니다.
- 이 튜토리얼에서는 시연 목적으로 JSON 자리 표시 자 API를 사용할 것입니다.
- API 제공 업체는 게시물, 댓글, 앨범, 사진, 토도 및 사용자와 같은 리소스를 제공합니다.
- 단순성을 위해 게시물 리소스에 중점을 둘 것입니다.
- 게시물에는 ID, 제목, 신체 및 사용자 ID가 있습니다.
- ABAP에서 REST API를 소비하려면 If_web_http_client라는 화이트리스트 ABAP API를 사용합니다.
- 우리는 또한 JSON과 협력하기 위해 XCO 라이브러리를 사용합니다.
질문:
- API는 무엇을 의미합니까??
API는 응용 프로그램 프로그래밍 인터페이스를 나타냅니다. - REST API는 무엇입니까??
REST API는 HTTP 프로토콜을 사용하여 API를 구축하고 URI를 통해 JSON 또는 XML 데이터를 보내거나 수신하는 패턴입니다. - Odata는 무엇입니까??
Odata는 SAP 세계에서 인기있는 REST API 유형입니다. - ABAP에서 외부 API 소비에 대한 정보가 많이 있습니까??
아니요, 특히 클라우드 ABAP 용 화이트리스트 API에 대한 정보가 제한되어 있습니다. - 이 튜토리얼에서 어떤 API 제공 업체를 사용할 것인가?
시연 목적으로 JSON 자리 표시 자 API를 사용할 것입니다. - JSON 자리 표시 자 API는 어떤 리소스를 제공합니까??
JSON 자리 표시 자 API는 게시물, 댓글, 앨범, 사진, 토도 및 사용자와 같은 리소스를 제공합니다. - 이 튜토리얼에서 어떤 리소스에 집중할 것인지?
우리는 단순성을 위해 게시물 리소스에 중점을 둘 것입니다. - 게시물에 어떤 속성이 있습니까??
게시물에는 ID, 제목, 신체 및 사용자 ID가 있습니다. - REST API를 소비하기 위해 사용하는 White Listed ABAP API?
우리는 if_web_http_client api를 사용할 것입니다. - JSON과 함께 일하는 데 어떤 라이브러리를 사용할 것인가?
우리는 XCO 라이브러리를 사용할 것입니다.
자세한 답변 :
- API는 무엇을 의미합니까??
API는 응용 프로그램 프로그래밍 인터페이스를 나타냅니다. 두 개의 응용 프로그램이 서로 통신 할 수있는 일련의 표준입니다. - REST API는 무엇입니까??
REST API는 HTTP 프로토콜을 사용하여 API를 구축하는 패턴입니다. 응용 프로그램이 URI를 통해 JSON 또는 XML 데이터를 보내고받을 수 있습니다. JSON 기반 REST API가 널리 사용됩니다. - Odata는 무엇입니까??
Odata는 SAP 세계에서 매우 인기있는 REST API의 유형입니다. SAP 시스템에 저장된 데이터에 쉽게 액세스하고 조작 할 수 있습니다. - ABAP에서 외부 API 소비에 대한 정보가 많이 있습니까??
아니요, ABAP에서 외부 API 소비에 대한 정보가 제한되어 있습니다. 특히 클라우드 ABAP와 함께 사용할 수있는 화이트리스트 API의 경우. 이 튜토리얼은 Cloud ABAP를 사용하여 REST API 소비에 대한 지침을 제공하는 것을 목표로합니다. - 이 튜토리얼에서 어떤 API 제공 업체를 사용할 것인가?
우리는 테스트 및 프로토 타이핑을 위해 무료로 사용하기위한 가짜 온라인 REST API 인 JSON 자리 표시 자 API를 사용할 것입니다. CRUD (생성, 읽기, 업데이트, 삭제) 작업을 수행 할 수 있습니다. - JSON 자리 표시 자 API는 어떤 리소스를 제공합니까??
JSON 자리 표시 자 API는 게시물, 댓글, 앨범, 사진, Todos 및 사용자와 같은 리소스를 제공합니다. 이 튜토리얼에서는 게시물 자원에 중점을 둘 것입니다. - 이 튜토리얼에서 어떤 리소스에 집중할 것인지?
우리는 JSON 자리 표시 자 API의 게시물 리소스에 중점을 둘 것입니다. 이를 통해 SAP 클라우드 플랫폼에서 화이트리스트 ABAP API를 사용하여 REST API에서 CRUD 작업을 실행하는 방법을 보여줄 수 있습니다. - 게시물에 어떤 속성이 있습니까??
게시물에는 ID, 제목, 신체 및 사용자 ID가 있습니다. ID는 게시물의 고유 식별자를 나타내고 사용자 ID는 게시물을 만든 사용자의 ID를 나타냅니다. - REST API를 소비하기 위해 사용하는 White Listed ABAP API?
ABAP에서 REST API를 소비하려면 IF_WEB_HTTP_CLIENT API를 사용합니다. SAP 클라우드 플랫폼에서 사용할 수있는 화이트리스트 ABAP API입니다. - JSON과 함께 일하는 데 어떤 라이브러리를 사용할 것인가?
JSON과 협력하기 위해 XCO (Extension Components) Library의 Cloud Platform Edition을 사용할 것입니다. 이 라이브러리는 Camelcase와 같은 다른 명명 규칙간에 JSON 데이터를 변환하는 데 유용한 기능을 제공합니다.
이 튜토리얼을 따르면 ABAP를 사용하여 REST API를 소비 할 수 있습니다.
(클라우드) ABAP를 사용하여 REST API를 소비합니다
후 메소드 호출 ->
SAP는 REST API를 사용합니까??
об йтоэ странице
м е р р регистрировали подо 착취 ay rzа ф징퍼, исход 넘추 타 ay сети. с пом거나 ю это인지 страницы м주는 сможем определить, что з просы отправляете именно, а не робот. почему это могло произойти?
эта страница отобр은 Âется в тех Â сл 나아가 · 추, ∈огда автомати인지 скими системи Google регтрирр곽막우 ся 테 추 법구추 추 님. котор ое нарушают условия использования. странира перестанет отобр은 жаться после того, как эти запросы прекратся. до отого момента для использования слу 갑기 Google необ 영향.
источником запросов может служить вредоносное по, подключаемые модули браузера или скрипт, насое 밑 밑 밑보관 сзлку ыапросов. если вл используете общий доступ в интернет, проблема 갑새 갑새 딘 악 с сомпером с с с с с саким 테 IP-адесом → Â 궤. обратитесь к своему системному администратору. подроб 변태.
проверка по слову может татак뿐 아니라 자기 появляться, если вы В 갑 갑격적 В Â водите слож ные запросы, об협 ораспронон혁 ™ rапротототототототото술도 있습니다. емами, или вводите запросы очень часто.
(클라우드) ABAP를 사용하여 REST API를 소비합니다
API는 애플리케이션 프로그래밍 인터페이스의 약자이며 두 응용 프로그램이 서로 대화 할 수있는 일련의 표준으로 구성됩니다. REST API는 건물 API의 특정 패턴입니다. URI를 통해 HTTP 프로토콜을 기반으로 JSON 또는 XML 데이터를 보내고 수신합니다 (균일 리소스 식별자). JSON 기반 REST API가 널리 퍼져 있습니다. 우리는 또한이 튜토리얼에서 그러한 것을 사용할 것입니다.
SAP 세계에서 매우 인기있는 Odata는 그 자체로 REST API입니다. ABAP에서 REST API를 제공하는 방법에 대한 정보가 많이 있습니다 (i.이자형., Odata 서비스를 게시하려면). 그러나 있습니다’t ABAP에서 외부 API를 소비하는 방법에 대해. 그리고 거의없는 곳에서, 그것은 비 설교가없는 ABAP API를 포함합니다.이자형., 클라우드 ABAP에는 사용할 수 없습니다. 그래서 Cloud ABAP를 사용하여 REST API 소비에 대한이 자습서를 작성하기로 결정했습니다.
대본
API 제공 업체
우리는 JSON 자리 표시 자와 협력 할 것입니다 – a “테스트 및 프로토 타이핑에 가짜 온라인 REST API를 무료로 사용할 수 있습니다”. 모든 CRUD (생성, 읽기, 업데이트, 삭제) 작업을 수행 할 수 있습니다. 공정하게 말하면, 생성, 업데이트 및 삭제는 실제로 작동하지 않지만 서버는 마치 마치 마치 마치 마치 가짜입니다. 이는 우리의 사용 사례에 충분합니다!
자원
API 제공 업체가 노출됩니다 게시물, 댓글, 앨범, 사진, 토도, 그리고 사용자. 단순성을 위해’Sake, 우리는 만 사용할 것입니다 게시물 자원, 나머지는 척합니다’t 거기. 내 튜토리얼의 주요 아이디어는 REST API에서 CRUD 액션을 실행하는 방법에 대한 매우 간단한 안내서를 제공하는 것입니다. SAP 클라우드 플랫폼 (CP)에서 화이트리스트 ABAP API를 사용하여이를 수행하십시오. 이것은 SAP CP 시험 계정 에서이 코드를 실행할 수 있음을 의미합니다.
게시물 자원
게시물에는 ID, 제목, 신체 및 사용자 ID가있어 게시물을 만든 사용자의 ID를 의미합니다. 우리는 그것을 다음과 같이 ABAP로 표현합니다
유형 : post_s, user_id type i, id type i, 제목 유형 문자열, 바디 유형 문자열, post_s, post_tt post_tt type type of post_s, post_without_id_s, user_id i, 제목 유형 문자열, 바디 타입 문자열, post_without_id_s의 끝.
Post ID가 REST API에 의해 자동으로 할당되므로 ID가없는 구조가 필요합니다. 새 게시물을 만들 때 우리가 그것을 제공하지 않음을 의미합니다.
클라우드 ABAP API가 사용되었습니다
HTTP 요청을 보내는 것
앞에서 언급했듯이 ABAP에서 REST API를 소비하기위한 소수의 기존 튜토리얼은 주로 비 중환자 ABAP API를 사용합니다. 예를 들어, if_http_client 클라우드 ABAP에서 사용할 수없는 사람. SAP 클라우드 플랫폼의 화이트리스트 ABAP API를 확인하는 방법은 릴리스 객체 기울기. Eclipse ABAP 개발 도구 (ADT) -> 프로젝트 탐색기 -> 릴리스 객체에서 액세스 할 수 있습니다. 따라서 HTTP 요청을 보내는 클라우드 지원 ABAP API는 다음과 같습니다 if_web_http_client. 클라이언트를 얻기 위해 다음 방법을 정의합니다
방법 : create_client 가져 오기 URL 유형 문자열 리턴 값 (결과) 유형 ref on if_web_http_client raising cx_static_check
메소드 create_client. data (dest) = cl_http_destination_provider => create_by_url (url). 결과 = cl_web_http_client_manager => create_by_http_destination (dest). endmethod.
URL은 입력 매개 변수입니다. 반환 된 결과는 생성 된 웹 HTTP 클라이언트입니다.
JSON과 함께 일합니다
JSON과 협력하기 위해 XCO의 클라우드 플랫폼 에디션을 사용할 것입니다확장 구성 요소) 도서관. 여기와 여기에 대해 자세히 알아보십시오. 사용 사례와 관련된 특정 클래스는 xco_cp_json. 그것이 제공하는 매우 귀중한 것은 다른 명명 규칙을 변화시키는 능력입니다. 예를 들어, Camelcase to Under_Score 및 다른 방법은.
나머지 API를 소비합니다
재미있는 부분에 도달하기 전에 몇 가지 상수를 정의해야합니다. 물론 이것은 엄격하게 필요하지 않지만 문자 리터럴과 달리 상수로 작업하는 것이 더 나은 연습이며 재사용 가능성을 허용합니다.
상수 : base_url 유형 문자열 값 'https : // jsonplaceholder.타입 코드.com/posts ', content_type 유형 문자열 값'content-type ', json_content 유형 문자열 값'응용 프로그램/json; charset = utf-8 '.
기본 URL은 단순히 주소입니다 게시물 자원. 후자의 두 상수는 우리가 데이터를 보낼 경우에 필요한 두 가지 상수를.이자형., REST API를 사용하여 서버에 생성 및 업데이트). 우리는 서버에 JSON을 보내고 있음을 알려야합니다.
모든 게시물을 읽으십시오
모든 게시물을 읽는 URL은 기본 URL입니다. 따라서 클라이언트를 작성하고 클라이언트를 사용하여 GET 요청을 실행하고 클라이언트를 닫고 수신 된 JSON을 게시물 테이블로 변환합니다. 게시물 유형 테이블은 게시물 자원 위의 섹션. 마지막에 전체 코드를 참조 할 수도 있습니다.
read_posts 리턴 값 (결과) 유형 post_tt raising cx_static_check
방법 read_posts. "모든 게시물 데이터 (URL)의 JSON을 얻습니다< base_url >|. data (client) = create_client (url). data (response) = client-> execute (if_web_http_client => get)-> get_text (). 클라이언트-> close (). "json을 표에 게시 할 수 있도록 xco_cp_json => data-> from_string (응답)-> apply (value #((xco_cp_json => transformation-> camel_case_to_underscore)))-> write_to (ref #(resat)). endmethod.
단일 게시물을 읽으십시오
단일 게시물을 읽는 방법은 비슷합니다. 게시물의 ID를 입력하는 차이점과 구조를 반환합니다.이자형., 테이블 대신 단일 게시물,) (i.이자형., 게시물 목록). 나머지 API’단일 게시물을 읽는 것의 URL은 다음과 같습니다
read_single_post 가져 오기 ID 유형 I 반환 값 (결과) 유형 post_s raising cx_static_check
메소드 read_single_post. "입력 포스트 ID 데이터 (URL) = |< base_url >/< id >|. data (client) = create_client (url). data (response) = client-> execute (if_web_http_client => get)-> get_text (). 클라이언트-> close (). "JSON 변환 구조 xco_cp_json => data-> from_string (응답)-> apply (value #((xco_cp_json => transformation-> camel_case_to_underscore)))-> write_to (ref #(resat)). endmethod.
게시물을 만듭니다
앞에서 설명한 바와 같이, 게시물’ ID는 REST API에 의해 자동으로 할당됩니다. 따라서 게시물을 만들기 위해 post_without_id_s 유형. 이것은 우리의 입력 매개 변수가 될 것입니다. 우리는이 ABAP 구조에서 JSON으로 전환하여 XCO 라이브러리를 다시 사용합니다. 거기에서 우리는 클라이언트를 만듭니다. 그런 다음 방금 만든 JSON으로 보내려고하는 HTTP 요청의 본문을 설정하고 JSON Content-Type을 보낼 것임을 서버에 알립니다. 마지막으로 게시물 요청을 실행하고 서버를 반환합니다’S 응답. 모든 것이 잘되면 서버’S Response는 새로 생성 된 ID (현재 100 개의 게시물이 있기 때문에 101)와 함께 게시물을 반환합니다.
create_post 가져 오기 post_without_id type post_without_id_s 리턴 값 (결과) 유형 문자열 raising cx_static_check
메소드 create_post. "입력 게시물을 JSON Data (json_post) = xco_cp_json => data-> from_abap (post_without_id)-> apply (value #((xco_cp_json => transformation-> oundscore_to_camel_case))))-> to_string (). "Post의 JSON을 서버로 보내고 응답 데이터 (URL) = |< base_url >|. data (client) = create_client (url). data (req) = client-> get_http_request (). req-> set_text (json_post). req-> set_header_field (i_name = content_type i_value = json_content). result = client-> execute (if_web_http_client => post)-> get_text (). 클라이언트-> close (). endmethod.
업데이트 게시물
PUT 요청으로 업데이트 할 것입니다. 이것은 우리가 전체 게시물을 제공한다는 것을 의미합니다. 반면에 패치는 업데이트 된 필드 만 제공 할 수 있습니다 (E.g., 제목 만). 이 흥미로운 것을 발견하면 패치를 직접 요청할 수 있습니다’여기에 제공된 자원에 너무 어려워 지십시오!
우리는와 비슷한 논리를 따릅니다 만들다 행동. 또한 입력 매개 변수로 게시물을 제공하지만 이번에는 전체 구조 (Post ID와 함께)를 사용합니다. 게시물을 업데이트하기위한 URL 은이 (단일) 게시물에 액세스하는 것과 동일합니다
따라서 유일한 차이점 만들다 변경된 유형의 게시물 입력 매개 변수, URL 및 HTTP 요청 메소드 (PUT)를 포함시킵니다.
update_post 포스트 유형 가져 오기 Post_s 리턴 값 (결과) 유형 문자열 Raising CX_STATIC_CHECK
메소드 update_post. "입력 게시물을 JSON 데이터 (json_post) = xco_cp_json => data-> from_abap (post)-> apply (value #((xco_cp_json => transformation-> comsscore_to_camel_case)))-> to_string (). "Post의 JSON을 서버로 보내고 응답 데이터 (URL) = |< base_url >/< post-id >|. data (client) = create_client (url). data (req) = client-> get_http_request (). req-> set_text (json_post). req-> set_header_field (i_name = content_type i_value = json_content). result = client-> execute (if_web_http_client => put)-> get_text (). 클라이언트-> close (). endmethod.
게시물 삭제
게시물을 삭제하는 것이 가장 간단한 요청입니다. 우리는 단순히 ID를 가져 와서 특정 게시물의 URL에 삭제 http 요청을 보냅니다. 사용자가 문제가 발생하면 서버를 확인합니다’S 응답 코드 (200이어야합니다 – 확인).
delete_post 가져 오기 ID 유형 I raising cx_static_check
메소드 delete_post. 데이터 (url) = |< base_url >/< id >|. data (client) = create_client (url). data (응답) = client-> execute (if_web_http_client => delete). 응답-> get_status () -code ne 200. 예외 유형을 높이십시오 CX_WEB_HTTP_CLIENT_ERROR. endif. endmethod.
코드 테스트
이제 우리는 모든 CRUD 기능을 제공 했으므로’s 확인하십시오! 이를 위해 우리는 그것을 구현할 것입니다 if_oo_adt_classrun 콘솔 응용 프로그램으로 클래스를 실행할 수있는 인터페이스. Java와 유사하게 실행되는 주요 방법이 있습니다.
방법 if_oo_adt_classrun ~ 메인. 노력하다. "데이터 읽기 (all_posts) = read_posts (). data (first_post) = read_single_post (1). "생성 데이터 (create_response) = create_post (value #(user_id = 7 title = 'hello, world!'body =':) ')). "First_Post-user_id = 777 업데이트. data (update_response) = update_post (First_Post). "Delete delete_post (9). "결과 인쇄-> 쓰기 (all_posts). out-> 쓰기 (First_Post). out-> 쓰기 (create_response). out-> 쓰기 (update_response). cx_root를 데이터로 잡아 (EXC). out-> write (exc-> get_text ()). 엔 트리. endmethod.
F9로 실행되는 다음 출력을 인쇄합니다
ABAP 콘솔에서 출력의 시작
ABAP 콘솔에서 출력 끝
결론
이것은 클라우드 ABAP에서 REST API를 소비하는 방법에 대한 자습서를 종료합니다. 나는 그것이 당신에게 유용했기를 바랍니다. 당신이 거기에 느끼면’S 개선 사항이 있거나 질문이나 피드백이 있으시면 의견에 알려주십시오!
전체 코드
클래스 ZSS_TESTER_2 정의 공개 최종 공개 생성. 공개 섹션. 인터페이스 : if_oo_adt_classrun. 유형 : post_s, user_id type i, id type i, 제목 유형 문자열, 바디 유형 문자열, post_s, post_tt post_tt type type of post_s, post_without_id_s, user_id i, 제목 유형 문자열, 바디 타입 문자열, post_without_id_s의 끝. 방법 : Create_Client URL 유형 문자열 값 (결과) 유형 ref on is_web_http_client cx_static_check, rebuding value (result) 유형 post_tt rating cx_static_check, read_single_post id value (result) 유형 _static_s postout _scock, create _static _check, create _check, create _static _check, read_spost _static _check. _ID_S 리턴 값 (결과) 유형 문자열 RAISING CX_STATIC_CHECK, UPDATE_POST 가져 오기 POST _S 리턴 값 (결과) 유형 문자열 CX_STATIC_CHECK, DELETE_POST ID 타입 IRISING CX_STATIC_CHECK RAISING CX_STATIC_CHECK. 개인 섹션. 상수 : base_url 유형 문자열 값 'https : // jsonplaceholder.타입 코드.com/posts ', content_type 유형 문자열 값'content-type ', json_content 유형 문자열 값'응용 프로그램/json; charset = utf-8 '. 엔드 클래스. 클래스 ZSS_TESTER_2 구현. 방법 if_oo_adt_classrun ~ 메인. 노력하다. "데이터 읽기 (all_posts) = read_posts (). data (first_post) = read_single_post (1). "생성 데이터 (create_response) = create_post (value #(user_id = 7 title = 'hello, world!'body =':) ')). "First_Post-user_id = 777 업데이트. data (update_response) = update_post (First_Post). "Delete delete_post (9). "결과 인쇄-> 쓰기 (all_posts). out-> 쓰기 (First_Post). out-> 쓰기 (create_response). out-> 쓰기 (update_response). cx_root를 데이터로 잡아 (EXC). out-> write (exc-> get_text ()). 엔 트리. endmethod. 메소드 create_client. data (dest) = cl_http_destination_provider => create_by_url (url). 결과 = cl_web_http_client_manager => create_by_http_destination (dest). endmethod. 방법 read_posts. "모든 게시물 데이터 (URL)의 JSON을 얻습니다< base_url >|. data (client) = create_client (url). data (response) = client-> execute (if_web_http_client => get)-> get_text (). 클라이언트-> close (). "json을 표에 게시 할 수 있도록 xco_cp_json => data-> from_string (응답)-> apply (value #((xco_cp_json => transformation-> camel_case_to_underscore)))-> write_to (ref #(resat)). endmethod. 메소드 read_single_post. "입력 포스트 ID 데이터 (URL) = |< base_url >/< id >|. data (client) = create_client (url). data (response) = client-> execute (if_web_http_client => get)-> get_text (). 클라이언트-> close (). "JSON 변환 구조 xco_cp_json => data-> from_string (응답)-> apply (value #((xco_cp_json => transformation-> camel_case_to_underscore)))-> write_to (ref #(resat)). endmethod. 메소드 create_post. "입력 게시물을 JSON Data (json_post) = xco_cp_json => data-> from_abap (post_without_id)-> apply (value #((xco_cp_json => transformation-> oundscore_to_camel_case))))-> to_string (). "Post의 JSON을 서버로 보내고 응답 데이터 (URL) = |< base_url >|. data (client) = create_client (url). data (req) = client-> get_http_request (). req-> set_text (json_post). req-> set_header_field (i_name = content_type i_value = json_content). result = client-> execute (if_web_http_client => post)-> get_text (). 클라이언트-> close (). endmethod. 메소드 update_post. "입력 게시물을 JSON 데이터 (json_post) = xco_cp_json => data-> from_abap (post)-> apply (value #((xco_cp_json => transformation-> comsscore_to_camel_case)))-> to_string (). "Post의 JSON을 서버로 보내고 응답 데이터 (URL) = |< base_url >/< post-id >|. data (client) = create_client (url). data (req) = client-> get_http_request (). req-> set_text (json_post). req-> set_header_field (i_name = content_type i_value = json_content). result = client-> execute (if_web_http_client => put)-> get_text (). 클라이언트-> close (). endmethod. 메소드 delete_post. 데이터 (url) = |< base_url >/< id >|. data (client) = create_client (url). data (응답) = client-> execute (if_web_http_client => delete). 응답-> get_status () -code ne 200. 예외 유형을 높이십시오 CX_WEB_HTTP_CLIENT_ERROR. endif. endmethod. 엔드 클래스.
REST API 생성 (Get & Post Method Call)
REST API는 REST 건축 스타일의 제약을 준수하고 편안한 서비스와의 상호 작용을 허용하는 표현 상태 전송 응용 프로그램 프로그래밍 인터페이스입니다.
가장 일반적인 방법은 다음과 같습니다. Get, Post, Put 및 Delete,
이 메소드는 사용됩니다, 레코드 검색 요청, 레코드 작성 후 요청, 레코드 업데이트 요청 및 삭제 요청 삭제 요청
시나리오 -> 드라이버 ID에 따라 드라이버 세부 사항을 제공해야합니다.
1 단계 ->
드라이버 데이터베이스 테이블.
2 단계 ->
요청 핸들러 클래스를 만듭니다 ‘zcl_driver_req_handler’ 표준 클래스와 물려받습니다 ‘cl_resthttp_handler’
참고 -> get_root_handler 메소드를 구현해야합니다. 그렇지 않으면 구문 오류가 발생합니다.
3 단계 ->
요청 제공자 클래스를 만듭니다 ‘zcl_driver_req_provider’ 표준 클래스와 물려받습니다 ‘cl_rest_resource’
4 단계 -> 이제 if_rest_resource를 구현하십시오 ~ 데이터를 읽는 메소드 GET.
데이터 호출을 읽은 후 /ui2 /cl_json => serialize () 메소드 ABAP 구조를 JSON 형식으로 변환하는 메소드.
5 단계 -> get_root_handler 요청 핸들러 클래스 방법을 구현하십시오.
여기에서 우리는 라우터의 도움으로 요청 핸들러 클래스 및 요청 제공자 클래스를 연결해야합니다.
6 단계 -> 서비스 요소, tcode sicf를 만듭니다
7 단계 -> 링크 핸들러 목록, 여기에서 요청 핸들러 클래스를 정의해야합니다 ‘zcl_driver_req_handler’.
8 단계 -> 서비스 활성화.
9 단계 -> 테스트 서비스.
결과 -> 여기에서 드라이버를 전달하고 ID 데이터를 기준으로 JSON 형식으로 표시됩니다.
후 메소드 호출 ->
시나리오 -> 데이터베이스에서 새로운 드라이버 세부 사항을 만들어야합니다. 당신은 드라이버 ID를 볼 수 있듯이 ‘002’ 시스템에만 존재하며 이제 새로운 ID ‘001’ 만들어야합니다.
가변 LV_DATA에서 데이터는 JSON 문자열로 제공됩니다
콜 /ui2 /cl_json => deserialize () 메소드 JSON 문자열을 ABAP 구조로 변환하는 메소드.
다음은 ID가있는 새 항목입니다 ‘001’
결론 ->
이 블로그를 읽은 후 간단한 REST API를 만들 수 있으며 요청 제공 업체 클래스에서 매개 변수를 읽는다는 아이디어가 있습니다.
수정이 필요한지 자유롭게 제안하십시오 🙂
ABAP에서 REST API 개발
최근 두 블로그에서 XML (Demo Application) 또는 JSON (Demo Application)을 사용하여 REST API의 웹 클라이언트를 작성하는 방법을 보여주었습니다. 이 블로그에서는 서버 측면에 중점을 둘 것입니다. REST API를 ABAP 요청 핸들러로 구현하는 방법. Migros BSP 웹 사이트에서 여기에서 논의하고있는 모든 코드를 검사 할 수 있습니다’s 모두 클래스 zcl_job_data .
ICF 트리
요청 핸들러는 인터페이스를 구현하는 클래스입니다. if_http_extension은 하나의 단일 메소드 handle_request로 구성됩니다. 요청 핸들러 클래스는 트랜잭션 SICF 경로에 첨부 될 수 있습니다. 들어오는 HTTP 요청은 인터넷 커뮤니케이션 프레임 워크에 의해 분석되어 요청 경로와 SICF 경로와 일치 시키려고합니다. 첨부 된 요청 핸들러가있는 노드가 발견 되 자마자 일치 프로세스가 중지됩니다. 이 경우 핸들러 클래스의 인스턴스가 생성되고 메소드 핸들 _request가 호출됩니다.
이 예제 서비스는 경로에 첨부됩니다 /직업/속성. 클래스 zcl_job_data는 요청 경로가 시작되는 모든 수신 요청에 대한 책임이 있다고 선언됩니다 /직업/속성 :
첫 번째 전략 : HTTP 요청 방법
인터페이스 방법의 구현 if_http_extension ~ handle_request () 최상위 수준의 처리를 형성합니다. 따라서 구현은 대략적인 처리 스켈레톤 만 제공합니다. 데이터베이스 작업을위한 인스턴스와 나머지 작업의 처리를위한 인스턴스가 생성되고, 요청 처리가 해당 인스턴스에 위임되며, 요청 처리를위한 인스턴스가 결정되지 않는 경우 오류 처리를위한 캐치 블록이 있습니다. 이러한 상황은 상태 코드에 대한 HTTP 응답을 초래해야합니다 ‘400 잘못된 요청’.
이 장소에서는 전략 설계 패턴을 사용하고 있습니다. HTTP 방법 (Get, Put, Post, Delete, Options)에 따라 특정 인스턴스가 생성됩니다. 가능한 각각의 사례는 특정 전략에 해당합니다.
방법 if_http_extension ~ handle_request . 데이터 : lo_db 유형 ref to lif_db, lo_rest type ref to lif_rest, lo_invalid_method type ref to zcx_error, lv_reason type string. 노력하다. * 데이터베이스 운영 객체 LO_DB ?= get_db (io_server = Server). * 동사 (Get, Put, Post, Options, Delete)에 따라 올바른 REST 핸들러 인스턴스 가져 오기 LO_REST ?= get_rest (io_server = Server io_db = lo_db). * 작동 lo_rest-> handle_request (). zcx_not_found를 lo_invalid_method로 잡으십시오. lv_reason = lo_invalid_method-> get_text (). Server-> response-> set_status (Code = 400 "나쁜 요청 이유 = lv_reason). 엔 트리. endmethod.
인스턴스 결정을 위해 명명 규칙을 사용하고 있습니다 : 클래스 lcl_rest_get은 http 동사 get, lcl_rest_put 등과 관련이 있습니다. 이 모든 클래스는 인터페이스 Lif_Rest를 구현합니다. 이런 식으로 동적 인스턴스 생성을 사용할 수 있습니다. 또는 우리는 큰 사건을 쓸 수있었습니다…’에스. 사건의 장점은 그 것입니다 객체를 만듭니다 구문 적 정확성을 정적으로 점검 할 수 있습니다. 나는 다이나믹 변형을 선택했습니다.
HTTP 요청 메소드 (Get, Put, Post,…)가 이름이있는 의사 헤더 필드로 사용할 수 있음을 관찰하십시오 ‘~ request_method’:
메소드 get_rest. 데이터 : LV_CLASSNAME 유형 SEOCLSNAME, LV_METHOD 유형 문자열, LV_MESSAGE TYPE TEXT255. lv_method = io_server-> request-> get_header_field ( '~ request_method'). lv_classname에 대한 'lcl_rest_'lv_method concatenate. 노력하다. 개체 생성 eo_rest 유형 (lv_className) 내보내기 io_request = io_server-> 요청 io_response = io_server-> 응답 io_db = io_db. cx_sy_create_object_error를 잡습니다. lv_message = 'method' '&' '지원되지 않음'(001). lv_message에서 '&'를 lv_method로 교체하십시오. _raise_with_text zcx_not_found lv_message. 엔 트리. endmethod.
두 번째 전략 : 데이터 전송 형식
이제 다른 HTTP 요청 방법에 대해 다른 핸들러 클래스가 있습니다. 그러나이 모든 핸들러에게는 몇 가지 일반적인 작업이 있습니다. 이러한 일반적인 작업 중 하나는 다음과 같습니다. 현재 데이터 전송 형식을 결정하고 사용 가능한 경우 입력을 ABAP 데이터로 변환하는 것입니다. ABAP 결과 데이터를 원하는 데이터 전송 형식 (XML 또는 JSON)으로 출력으로 변환하는 것입니다.
이제 Get과 같은 일부 요청 방법은 요청 내용이 필요하지 않습니다. 따라서 들어오는 데이터의 변환은 컨텐츠 데이터가 필요한 메소드 핸들러에 의해 수행됩니다. 반면에, 항상 다음과 같은 데이터 유형의 결과가 있습니다
유형 : ty_result의 시작, msgtype 유형 symsgty, 메시지 type c 길이 255, 작업 유형 zjobs_tab, ty_result의 끝.
작업 테이블에 항상 출품작이 없을 수도 있습니다. 그러나이 구조의 모든 구성 요소가 초기가되는 것은 아닙니다. 작업 테이블이 없으면 보통 메시지가 있습니다. 결과의 변환은 항상 수행 할 수 있습니다.
컨텐츠 유형 당 변환 알고리즘을 포함하는 특정 서브 클래스 인 Abstract Converter 클래스와 협력하는 것이 합리적입니다. 이것은 전략 패턴의 두 번째 적용입니다.
클래스 lcl_converter 정의 초록. 공개 섹션. class-methods get_instance 가져 오기 IV_ACCEPT 유형 문자열 리턴 값 (eO_Instance) 유형 참조 lcl_converter. 메서드 content_type 초록 반환 값 (ev_content_type) 유형 문자열. 메서드 get_entered_data 초록 가져 오기 IV_CDATA 유형 문자열 스트링 내보내기 es_job 유형 Zjobs ZCX_PARSE_ERRROR. 메소드 result_to_cdata 초록 가져 오기 is_result type ty_result 내보내기 ev_cdata type string. 엔드 클래스. "lcl_converter 정의
정적 메소드 lcl_converter => get_instance ()는 수용하다 HTTP 요청의 헤더 필드 :
클래스 LCL_CONVERTER 구현. 메소드 get_instance. IV_ACCEPT CS 'Application/JSON'인 경우. 객체 eo_instance 유형 lcl_json_converter를 만듭니다. 또 다른. 객체 eo_instance 유형 lcl_xml_converter를 만듭니다. endif. endmethod. "get_instance endclass. "LCL_CONVERTER 구현
모든 요청에 대한 공통 플롯
모든 특정 메소드 핸들러의 수퍼 클래스 LCL_REST로 공통 작업을 추출하여 인터페이스를 구현할 수 있습니다 LIF_REST ~ HANDE_REQUEST () 모든 서브 클래스에 대해 한 번.
SuperClasse의 공통 코드는 특정 코드와 혼합되어 서브 클래스에서 구현하고 해당 서브 클래스의 특정 동작을 정의해야합니다. 이를 달성하기 위해 우리는 원하는 시점에서 전화합니다 LIF_REST ~ HANDE_REQUEST (), 추상적 인 방법 하다( ), 서브 클래스에서 재정의되어야합니다. 이 do () 메소드에는 특정 조치가 포함됩니다.
이제 수퍼 클래스의 공통 구현 Lif_Rest ~ handle ()은 처리의 흐름 만 정의하여 콘크리트 동작을 서브 클래스 또는 go_converter:
- 전화하여 특정 조치를 실행하십시오 하다(),
- HTTP 오류 코드 400이 포함 된 오류 처리 “나쁜 요청” 변환 오류 (잘못된 데이터)의 경우, 응용 프로그램 오류의 경우 오류 메시지에 대한 응답 데이터를 설정하는 경우,
- 결과 구조는 해당 변환기 인스턴스를 사용하여 응답 데이터 구조 (XML 또는 JSON)에 매핑됩니다,
- 마지막으로 응답 데이터는 HTTP 응답 본문에 배치되며 적절한 응답 유형도 설정됩니다. Application/JSON 또는 Text/XML.
이것은 일반적인 스케치입니다 – 유효한 응답 처리 모두 HTTP 요청 방법 및 모두 콘텐츠 유형 (XML 및 JSON). 세부 사항은 호출 된 방법에 포함되어 있습니다.
메소드 LIF_REST ~ HANDE_REQUEST. 데이터 : lo_ex 유형 Ref to CX_ROOT, LV_CDATA 유형 문자열, ls_result type ty_result. 노력하다. * 특정 작업을 실행합니다 (ES_RESULT = LS_RESULT 가져 오기). ZCX_PARSE_ERROR를 LO_EX로 잡으십시오. go_response-> set_status (code = 400 "나쁜 요청 이유 = lo_ex-> get_text ()). set_response_parameters (). 반품. zcx_error를 lo_ex로 잡으십시오. ls_result-message = lo_ex-> get_text (). ls_result-msgtype = 'e'. 엔 트리. * 결과 구조를 JSON 또는 XML로 변환합니다. 각각 호출 메소드 go_converter-> result_to_cdata 내보내기 is_result = ls_result 가져 오기 ev_cdata = lv_cdata. * 응답 본문 통화 방법 Set_Response 내보내기 IV_CONTENT_TYPE = GO_CONVERTER-> CONTST_TYPE () IV_CDATA = LV_CDATA에 결과를 배치합니다. endmethod. "핸들 _request
특정 작업 – 풋 요청
허락하다’s 그림을위한 특정 작업을 살펴 봅니다. 풋 요청 – 데이터베이스에서 주어진 ID에 대한 작업 속성을 업데이트하거나 삽입하는 작업입니다. 디자인의 다음과 같이 자체 클래스 LCL_REST_PUT 처리 요청이 있습니다. 실제로이 요청 처리기에는 하다 구현 방법 자체 (특정 작업 클래스가 구현하려는 절대 최소값입니다 하다() 부모 수업에서 추상입니다. 구현이 없으면 인스턴스를 구축 할 수 없습니다.) : :
lcl_rest에서 상속 된 클래스 lcl_rest_put 정의. 보호 섹션. 방법은 재정의를 수행합니다. 엔드 클래스. "lcl_rest_put 정의
구현은 다음과 같습니다
- 지정된 ID가있는 작업은 데이터베이스에서 읽습니다 (만약에 ID가 지정되었습니다 – 새로운 작업의 경우 그렇지 않습니다),
- 입력 된 데이터는 적절한 것을 사용하여 LS_JOB 구조로 구문 분석됩니다 go_converter 사례,
- 그리고 마지막으로, 구하다() 메소드가 호출됩니다. 다른 요청 방법도 사용하므로 슈퍼 클래스로 구현됩니다.
클래스 lcl_rest_put 구현. 방법. 데이터 : ls_job 유형 zjobs, lv_id 유형 zjobs-id. 노력하다. get_job_by_id (ES_JOB = LS_JOB 가져 오기). lv_id = ls_job-id. zcx_not_found를 잡습니다. 엔 트리. 클리어 ls_job. 통화 방법 go_converter-> get_entered_data 내보내기 iv_cdata = go_request-> get_cdata () es_job = ls_job 가져 오기. LS_JOB가 초기가 아닌 경우. LV_ID가 초기가 아닌 경우. ls_job-id = lv_id. endif. 저장 (CS_JOB = LS_JOB 변경). es_result-message = 'job & saved a Saved'(002). es_result-message에서 '&'를 ls_job-id로 교체하십시오. es_result-msgtype = 's'. "성공 메시지는 ls_job를 테이블 es_result-job에 삽입합니다. endif. endmethod. "엔드 클래스를하십시오. "lcl_rest_put 구현
이 작업의 구현은 그렇지 않습니다’t HTTP 데이터 구조, 실제로 사용중인 형식 또는 전송 데이터 형식의 세부 사항에 대한 관리. 단순히 ABAP 데이터 구조와 함께 작동합니다 LS_JOB 입력 및 es_result 출력을 위해.
세션, 신원 및 잠금
테스트 애플리케이션 (JSON 앱이나 XML 앱에서)에서 데이터의 로그인이나 eenqueue가 없습니다. 응용 프로그램은 모든 사람을 위해 열려 있기 때문에 I Don 이후에만 작동합니다’티 정말 데이터베이스 테이블 zjobs에서 작동합니다. 실제로 응용 프로그램에 전화하는 각 고객은 자신의 세션 데이터와 함께 작동하므로’t 다른 사용자와 충돌합니다’ 운영, 다른 사용자가 방해받지 않습니다. 세션 데이터는 서버 측 쿠키로 그를 위해 보존되어 단일 대화 단계에서 살아남을 수 있습니다 (예 : 페이지를 다시로드하면 데이터의 현재 상태가 재현됩니다).
웹 클라이언트가 BSP로 작성되면 속성에 사용할 수있는 세션 ID가 있습니다 runtime-> server_id. 이 세션 ID는 요청을 한 특정 브라우저 인스턴스를 식별합니다. 클라이언트 측 에서이 세션 ID는 항상 쿠키에 포함되어 있습니다 SAP-AppContext. 응용 프로그램에 세션 ID와 함께 보존되어야하는 상태가있는 경우 SAP-AppContext 쿠키에서 ID를 추출해야하며 모든 AJAX 요청과 함께 쿼리 매개 변수로 전달되어야합니다. 다음은 쿠키에서 SAP-AppContext를 추출하는 기능입니다
함수 get_appContext () < var lAppcontextCookie = document.cookie.match(/sap-appcontext=(.*?)(?:;|$)/); return lAppcontextCookie && ( lAppcontextCookie.length >= 2) && unescape (lappcontextCookie [1]) || "";; >
이 기능에서 반환 된 AppContext는 모든 AJAX 요청과 함께 쿼리 매개 변수로 전달 될 수 있습니다. 서버 측에서 세션 ID는 해당 매개 변수에서 추출 할 수 있습니다
메소드 get_session_id. 데이터 : LV_APP_CONTEXT TYPE String, lv_app_context64 유형 문자열. * AJAX 요청 LV_APP_CONTEXT64 = IO_SERVER-> request-> get_form_field ( 'SAP_APPCONTEXT')에서 제공하는 양식 필드를 읽으십시오. LV_APP_CONTEXT64가 초기가 아닌 경우. * base64 decode lv_app_context = cl_http_utility => decode_base64 (lv_app_context64). * Session-id 찾기 regex 'sap-sessionid = ([^;]+)를 추출합니다?:; | $) 'in lv_app_context submatches ev_session_id. endif. EV_SESSION_ID가 처음 인 경우. ev_session_id = io_server-> session_id. endif. endmethod.
22 행에서 폴백으로 서버-> session_id가 사용됩니다. 그러나 각 요청에 대한 새로운 서버-> 세션_ID가 있으므로 각 대화 단계마다 새로운 세션 데이터가 발생합니다. 세션 관리가 실제로 필요한 경우 세션 ID가 서버로 전달되는 것이 필수적입니다.
세션 ID를 로그인 절차와 결합하는 것이 좋습니다. 사용자가 인증하면 브라우저가 제한된 유효성으로 세션 ID를받습니다. 해당 세션 -ID는 각 연속적인 휴식 작업마다 전달되어야합니다. ABAP에서 데이터베이스 액세스 클래스 CL_BSP_SERVER_SISSE_COOKIE를 통해 데이터베이스 테이블 SSCOOKIE에 세션 별 데이터를 저장하고 검색하는 데 사용할 수 있습니다.
이 세션 ID와의 로그인과의 커플 링은 HP 품질 센터의 나머지 API가 작동하는 방식입니다.
ABAP 사용’S 내장 JSON 변환기
XML 변환기 인스턴스는 XML-> ABAP의 XSLT 변환을 호출하는 데있어 매우 간단하지만 다른 방법으로는 JSON 변환이 정확히 같은 방식으로 처리 될 수 있다는 것은 놀라운 일이 될 수 있습니다. 이것은 이후로 가능합니다 호출 변환 진술은 JSON 형식을 지원합니다 (적어도 SAP_BASIS 702에 따라). JSON은 자동 감지 및 중간 JSON-XML 형식으로 구문 분석됩니다. 이것은 임의의 XSLT 변환으로 처리 될 수 있으며 다른 XML 문서 또는 ABAP 데이터로 변환 할 수 있습니다.
예를 들어, 테스트 응용 프로그램의 PUT 요청은 다음 JSON 데이터를 서버로 보낼 수 있습니다
이 내용의 문자열이 전달되는 경우 “소스 XML” ABAP에’S Call Transformation 문서, JSON은 이와 같은 XML 표현으로 구문 분석됩니다 (형식은 이해하기 쉽습니다 – 여기서 분명한 설명이 필요하지 않다고 생각합니다)
Call Transformation 문을 사용하여 임의의 XSLT 변환을 처리하고 JSON 문자열을 소스로 전달할 때 XSLT는이 내부 JSON-XML 표현에서 작동합니다. 이러한 JSON-XML 문서를 ABAP 데이터로 변환하는 것은 쉽습니다.보다 정확하게 : ABAP 데이터의 ASXML 표현으로 변환합니다. 예를 들어 다음 XSLT 변환을 고려하십시오
JSON 문자열에 적용되면 다음과 같은 결과가 발생합니다
0001 RSNAST00 uxpd_kube_kv 2 엑스 Rainer Zufall 모든 영업 주문 확인을 출력합니다
이것은 유효한 ABAP 데이터 설명입니다. 변환의 이름이 Zjson2job이라는 경우 데이터를 구성 요소 ID, Repid 등으로 ABAP 데이터 구조로 간단히 가져올 수 있습니다.
클래스 LCL_JSON_CONVERTER 구현. 메소드 get_entered_data. 데이터 : cx_transformation_error에 대한 lo_ex 유형 참조. ES_JOB를 클리어합니다. IV_CDATA CN 공간을 확인하십시오. 노력하다. 통화 변환 zjson2job 소스 XML IV_CDATA 결과 작업 = es_job. cx_transformation_error를 lo_ex로 잡으십시오. REAS_PARSE_ERROR (LO_EX). 엔 트리. endmethod. "get_entered_data
자신의 XSLT 변환을 전혀 정의 할 필요없이 Identity Transformation ID로 많은 일을 수행 할 수 있습니다. 웹 애플리케이션에 사용될 JSON 데이터 구조를 부과 할 수 있다면 그러한 A를 사용하는 것이 유리합니다 “표준” 구조. 예를 들어, JSON 해시를 작업 속성으로 다른 해시로 포장하여 상징적 인 키 이름의 값으로 만듭니다 “직업”:
그런 다음 데이터를 정의 XSLT 변환을 개발할 필요없이 구조로 구문 분석 할 수 있으며, ID를 사용하여 간단합니다
통화 변환 ID 소스 XML IV_CDATA 결과 작업 = es_job.
이 예에서는 웹 클라이언트와 서버 측 처리를 작성 했으므로이 점을 더 선택할 수있었습니다 “표준” 체재. 그러나 그것을 쫓지 않음으로써, 나는보다 유연한 JSON 데이터 형식으로 작업하는 방법을 배웠습니다.
함께 일하는 데 몇 가지 이유가 있습니다 “비 캐논형” ABAP 데이터의 JSON 표현 :
- JSON 형식은 웹 응용 프로그램에 유리하게 설계 될 수 있습니다 – 데이터 작업 작업 클라이언트 JavaScript 코드의 가독성을 최적화합니다.
- 특정 JSON 형식이 필요한 클라이언트 구성 요소가있을 수 있습니다. 예를 들어, jQuery DataTable은 테이블 데이터를 배열 배열로 전달해야합니다 : http : // www.데이터 타이블.NET/RELEASE-DATATABLE/예제/DATA_SOURCES/AJAX.HTML
- JSON 기반 타사 서비스는 ABAP 측에서 호출 될 수 있습니다 (HTTP 클라이언트 객체 포함)
- ABAP 데이터 일 수 있습니다 예상 필수 데이터로, 메시지 크기를 실제로 필요한 데이터로 줄입니다.
그냥 설명하기 위해’s 다른 변환을 살펴 봅니다. 서버에서 클라이언트로 나가는 길. 다시, 형식은 약간 다릅니다 “표준” ABAP 측 처리를 상당히 단순화하는 JSON 형식. 언급했듯이 결과 데이터 구조에는 포함됩니다
- 메세지,
- 메시지 유형,
- 그리고 직업 속성 테이블 :
유형 : ty_result의 시작, msgtype 유형 symsgty, 메시지 type c 길이 255, 작업 유형 zjobs_tab, ty_result의 끝.
다음 형식은이 구조에 대한 완벽한 JSON 펜던트입니다. 그것은 단순히 정체성 변환으로 생성 될 수 있으며 “소스 결과 = ls_result” (어디 ls_result 유형의 구조입니다 ty_result) : :
- 모든 구성 요소 이름은 JSON HASH 키 이름과 완벽하게 일치합니다,
- 내부 테이블은 해시의 JSON 어레이로 매핑되며 각 해시는 테이블의 하나의 항목을 나타냅니다,
- 그리고 상징적 인 이름을 가진 최상위 해시가 있습니다 “결과” 완전한 일을 위해 :
그러나 REST API가 지원하는 JSON 형식은 실제로 일부 세부 사항에서 다릅니다
- 작업은 배열이 아니라 해시로 설계되었습니다.
- 중복 해시가없고 모든 것을 키의 값으로 감싸십시오.
- msgtype의 구성 요소는 다릅니다. 단순히 유형이라고합니다.
예제 예는 다음과 같습니다
< "JOBS": < "0001": < "REPID": "RSNAST00", "VARID": "UXPD_KUBE_KV", "PRIO": "2", "RESTART": "X", "CONTACT": "Rainer Zufall", "DESCR": "Output all sales order confirmations" >, "0002": < "REPID": "RBDAPP01", "VARID": "UXPD_EDI_GUT02", "PRIO": "3", "RESTART": "X", "CONTACT": "Herbert Hurtig", "DESCR": "Credit Memos" >>, "메시지": "", "type": "">
ABAP 데이터 유형에 따라 다른 방향으로 만 위와 비슷한 방식으로 진행합니다 ty_result, 이 JSON 데이터 문자열에 해당하는 내부 JSON-XML 형식을 얻기 위해 XSLT 변환을 작성합니다.
원하는 JSON 데이터 문자열의 JSON-XML 데이터 형식은 다음과 같습니다
그래서 이것은 변형의 결과로 얻어야하는 목표입니다. 반면에, 구조의 ASXML 형식 Ty_result는 다음과 같습니다
0001 RSNAST00 uxpd_kube_kv 2 엑스 Rainer Zufall 모든 영업 주문 확인을 출력합니다 0002 RBDAPP01 uxpd_edi_gut02 삼 엑스 허버트 허버 신용 메모 시험 나
그리고 이것은 변환을 수행 할 XSLT 프로그램입니다
우리는 기본적으로 각각의 편차에 대해 “표준” ABAP 데이터의 JSON 표현,이 편차를 처리하는 XSLT 변환에 템플릿이 있습니다. 예를 들어, 대상의 msgtype 대신 다른 이름 유형은 템플릿으로 처리됩니다
ID는 재 배열되어야합니다. Zjobs 데이터 구조의 간단한 속성이므로 해시의 키가 되려면 한 레벨을 높이어야합니다. ID를 제외한 다른 모든 속성은 결과에 문자열 노드로 복사됩니다. 이를 위해서는이 두 템플릿이 필요합니다
ty_result 데이터 객체를 예상 형식의 JSON 문자열로 매핑하는 것은 이제 다음 코드로 ABAP에서 수행됩니다
메소드 result_to_cdata. 데이터 : lo_writer type ref to cl_sxml_string_writer. lo_writer = cl_sxml_string_writer => create (type = if_sxml => co_xt_json). 통화 변환 zjobs2json 소스 데이터 = is_result 결과 xml lo_writer. ev_cdata = cl_abap_codepage => convert_from (lo_writer-> get_output ()). endmethod. "result_to_cdata
저것’S ALL : EV_CDATA는 JSON 데이터 문자열을 포함하여 HTTP 응답 본문에 배치됩니다.
요약
ABAP에서 REST API의 구현에 관한 몇 가지 전형적인 주제를 설명했습니다. 다음과 같은 패턴을 적용하여 별도의 (로컬 또는 글로벌) 클래스에서 별도의 우려 사항을 유지할 수 있습니다 전략. 이것이 내 데모 REST API를 제공하는 클래스 ZCL_JOB_DATA가 구성되는 방식입니다 (이 블로그에서 기본 아이디어에 대해 논의되었습니다)
SAP ABAP로 REST API를 생성하고 MVC1 라우팅을 적용하는 방법
이 블로그 게시물에서는 REST API를 만드는 방법과 MVC1 라우팅을 적용하여 컨트롤러 클래스에서 다른 요청을 처리하는 방법을 보여줍니다.
이를 위해 먼저 휴식 구조를위한 핸들러 및 컨트롤러 클래스를 생성합니다. 그런 다음 MVC1 컨트롤러 클래스 및 모델 클래스를 추가하여 비즈니스 로직을 처리합니다.
그리고 마지막으로 우리는 휴식 요청을 처리 할 수있는 서비스를 만들 것입니다.
게시물이 끝나면 웹 브라우저, 우체부 및 ABAP가 동일한 REST API에 대한 소비 예제가 있습니다.
SAP REST에 대한 자세한 내용을 보려면 REST 튜토리얼을 살펴보십시오.
다음 구조를 만듭니다;
- zrest_s_resp_state
- zrest_s_response
- zrest_s_request
- zrest_s_resp_state
- zrest_s_response
이제 우리는 할 것입니다 수업을 만듭니다.
전화를 받으려면 스택을 통화하십시오
- zrest_cl_defs
- zrest_cl_model
- zrest_cl_req_controller
- zrest_cl_req_http_handler
- zrest_cl_http_handler
클래스 zrest_cl_defs 정의 공개 공개 . 공개 섹션. 상수 C_STATE_SUCCESS TYPE char1 value '## no_text. 상수 c_state_warning 유형 char1 value 'w'## no_text. 상수 C_STATE_ERROR TYPE char1 value 'e'## no_text. 보호 섹션. 개인 섹션. 엔드 클래스. 클래스 zrest_cl_defs 구현. 엔드 클래스.
클래스 zrest_cl_model 정의 public final 공개 생성 . 공개 섹션. 방법 get_dateTime 내보내기 !response_body type zrest_s_response-body !상태 유형 zrest_s_response-state . 보호 섹션. 개인 섹션. 엔드 클래스. 클래스 zrest_cl_model 구현. * ---------------------------------------------------------------------------------------+ * | 인스턴스 공개 방법 zrest_cl_model-> get_dateTime * + ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | [방법 get_dateTime. 데이터 : cx_root에 대한 exref type ref. 노력하다 . 유형 : ty_res의 시작, datetime type tzntimestp, ty_res의 끝. 데이터 : res type ty_res. res-datetime = sy-datum && sy-uzeit. response_body = /ui2 /cl_json => Serialize (데이터 내보내기 = RES). state-state = zrest_cl_defs => c_state_success. cx_root를 Exref로 잡으십시오. state-state = zrest_cl_defs => c_state_error. state-state_text = exref-> get_text (). 엔 트리. endmethod. 엔드 클래스.
클래스 zrest_cl_req_controller 정의 public final 공개 생성 . 공개 섹션. 방법 process_request 가져 오기 !req_json 유형 문자열 내보내기 !response_json 유형 문자열 !응답 _stc 유형 zrest_s_response . 보호 섹션. 개인 섹션. 상수 : C_REQ_GET_DATETIME 유형 zrest_e_req_id value '1001'. 메소드 CONCH_STC_TO_JSON 가져 오기 응답 _stc 유형 zrest_s_response 반환 값 (결과) 유형 문자열. 엔드 클래스. 클래스 zrest_cl_req_controller 구현. * ---------------------------------------------------------------------------------------+ * | 인스턴스 비공개 방법 zrest_cl_req_controller-> concl_stc_to_json * + ------------------------------------------------------------------------------------------------------------------------------ * | [--->] response_stc 유형 zrest_s_response * | [메소드 CONV_STC_TO_JSON. 데이터 : cx_root에 대한 exref type ref. 노력하다 . result = /ui2 /cl_json => Serialize (데이터 내보내기 = response_stc). CX_ROOT를 잡으십시오. 결과 = exref-> get_text (). 엔 트리. endmethod. * ---------------------------------------------------------------------------------------+ * | 인스턴스 공개 방법 zrest_cl_req_controller-> process_request * + --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | [--->] req_json 유형 문자열 * | [Method Process_Request. 데이터 : cx_root에 대한 exref type ref. 노력하다 . 데이터 req_stc 유형 zrest_s_request. /ui2/cl_json => deserialize (json을 내보내기 = req_json 데이터 변경 = req_stc). req_stc-id가 초기가 아닌 경우. 데이터 (모델) = new Zrest_cl_model (). req_stc-id eq c_req_get_dateTime 인 경우. model-> get_dateTime (repsing _body = response_stc-body state = response_stc-state). 또 다른. response_stc-state-state = zrest_cl_defs => c_state_warning. response_stc-state-state_text로 메시지 s001 (zrest_msg)을 메시지로 표시합니다. endif. 또 다른. "더미 컨텐츠를 샘플 req_stc-id = 999999로 채 웁니다. req_stc-body = '일부 json 컨텐츠'. response_stc-body = /ui2 /cl_json => Serialize (데이터 내보내기 = req_stc). response_stc-state-state = zrest_cl_defs => c_state_warning. response_stc-state-state_text로 메시지 s002 (zrest_msg)를 메시지로 표시합니다. endif. response_json = conv_stc_to_json (response_stc = response_stc). CX_ROOT를 잡으십시오. response_stc-state-state = zrest_cl_defs => c_state_error. response_stc-state-state_text = exref-> get_text (). response_json = conv_stc_to_json (response_stc = response_stc). 엔 트리. endmethod. 엔드 클래스.
클래스 zrest_cl_req_http_handler 정의 공개 상속에서 cl_rest_resource 최종 공개 생성 . 공개 섹션. 방법 if_rest_resource ~ 재정의를 얻습니다 . 방법 if_rest_resource ~ 사후 재정의 . 보호 섹션. 개인 섹션. 엔드 클래스. 클래스 zrest_cl_req_http_handler 구현. * ---------------------------------------------------------------------------------------+ * | 인스턴스 공개 방법 zrest_cl_req_http_handler-> if_rest_resource ~ if_rest_resource ~ get * + -------------------------------------------------------------------------------------------------------------------------- * +-------------------------------------------------------------------------------------- 방법 if_rest_resource ~ get. data (req_json) = mo_request-> get_uri_query_parameter (iv_name = 'req'iv_encoded = abap_false). 데이터 (컨트롤러) = new Zrest_cl_Req_controller (). Controller-> Process_Request (내보내기 req_json = req_json 가져 오기 응답 _json = data (response_json)). mo_response-> create_entity ()-> set_string_data (iv_data = response_json). endmethod. * ---------------------------------------------------------------------------------------+ * | 인스턴스 공개 방법 zrest_cl_req_http_handler-> if_rest_resource ~ post * + ------------------------------------------------------------------------------------------------------------------------------- * | [--->] io_entity type ref to if_rest_entity * +-------------------------------------------------------------------------------------- 방법 if_rest_resource ~ post. data (req_json) = mo_request-> get_entity ()-> get_string_data (). 데이터 (컨트롤러) = new Zrest_cl_Req_controller (). Controller-> Process_Request (내보내기 req_json = req_json 가져 오기 응답 _json = data (response_json)). mo_response-> create_entity ()-> set_string_data (iv_data = response_json). endmethod. 엔드 클래스.
CSRF는 아래 핸들러에서 비활성화되었습니다. 서비스의 GUI 매개 변수에서 비활성화하면 작동하지 않습니다. 휴식을 위해 핸들 _csrf_token을 구현해야합니다.
클래스 zrest_cl_http_handler 정의 cl_rest_http_handler에서 공개 상속 공개 공개 . 공개 섹션. "라우팅을 제공합니다. 이 방법에서 라우팅 경로가 컨트롤러에 할당됩니다. if_rest_application ~ get_root_handler 재정의 . 보호 섹션. "비활성화하려면 해당 방법을 재정의하십시오. 빈 방법으로. 메소드 handle_csrf_token 재정의 . 개인 섹션. 엔드 클래스. 클래스 zrest_cl_http_handler 구현. * ---------------------------------------------------------------------------------------+ * | 인스턴스 보호 방법 zrest_cl_http_handler-> handle_csrf_token * + ---------------------------------------------------------------------------------------------------------------------------------- * | [--->] io_csrf_handler 유형 ref to if_rest_csrf_handler * | [--->] io_request type ref to if_rest_request * | [--->] io_response type ref to if_rest_response * +-------------------------------------------------------------------------------------- 메소드 핸들 _csrf_token. * Call Method Super-> handle_csrf_token * 내보내기 * io_csrf_handler = * io_request = * io_response = * . endmethod. * ---------------------------------------------------------------------------------------+ * | 인스턴스 공개 방법 zrest_cl_http_handler-> if_rest_application ~ get_root_handler * + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ * | [메소드 if_rest_application ~ get_root_handler. "라우팅을 제공합니다. "서비스 경로/SAP/BC/REST"샘플 URL http : // vhcalnplci : 8000/SAP/BC/REST/Zrest/REST?sap-client = 001 & req = data (root_handler) = new Cl_rest_router (). root_handler-> 첨부 (IV_TEMPLATE = '/REST' "리소스의 통합 이름 IV_HANDLER_CLASS = 'ZREST_CL_REQ_HTTP_HINDLER'"객체 유형 이름). * "더 많은 요청 핸들러 클래스를 추가 할 수 있습니다 *"서비스 경로/SAP/BC/REST * "샘플 URL http : // vhcalnplci : 8000/sap/bc/rest/zrest/rest2?sap-client = 001 & req = * root_handler-> 첨부 ( * 내보내기 * iv_template = '/rest2' "리소스의 Unified Name * ivhandler_class = 'zrest_cl_req_http_handler2'"객체 유형 이름 *). ro_root_handler = root_handler. endmethod. 엔드 클래스.
그리고 마지막 단계, 서비스를 만듭니다.
SICF Tcode를 열고 실행하십시오.
/SAP/BC/REST로 이동하여 새 하위 요소 추가
설명 추가 및 핸들러 목록 탭과 클래스, zrest_cl_http_handler로 이동.
서비스 활성화. 서비스 마우스 오른쪽 버튼을 클릭하고 테스트를 클릭하십시오. 브라우저가 열립니다. 요청을 처리 /휴식하도록 URL을 변경하십시오.
제 경우에는 http : // vhcalnplci : 8000/sap/bc/rest/zrest/나머지
Get Request에서 일부 매개 변수를 전달하려면 다음과 같은 쿼리 문자열 매개 변수를 추가하십시오 ‘http : // vhcalnplci : 8000/sap/bc/rest/zrest/rest?SAP-Client = 001 & Req =’
핸들러에서 CSRF를 비활성화하지 않으면 우체부의 우편 메소드 또는 서버 자체와 다른 클라이언트와 같은 비 게이트 메소드를 호출하는 데 문제가 있습니다.
따라서 내 예에서는 CSRF를 비활성화했습니다.
우체부 예
기본 인증 매개 변수
예제와 결과를 얻으십시오
사후 예와 결과
ABAP에서 소비합니다
우리는 httpclient를 사용하여 전화를 걸고 get_dateTime 예제와 함께 JSON을 ABAP 구조로 구문 분석합니다.
HTTP 클라이언트 코드
클래스 zutil_cl_rest_ws 정의 공개 공개 . "휴식 웹 서비스 호출 공개 섹션을위한 클래스 래퍼. "상수 상수 : c_content_type_json 유형 문자열 값 '응용 프로그램/json; charset = utf-8', c_content_type_xml type string value 'application/xml; charset = utf-8', c_request_method_get String value 'get', c_request_method_post 'post'. "ws 호출 메소드 Call_ws 가져 오기 값 (i_url) 유형 문자열 값 (i_content_type) 유형 string default c_content_type_json value (i_request_method) 유형 string default c_request_request_method_get vale (i_username 옵션 값) 유형 값 값 (i_pay value). util_cl_defs => gty_state value (e_response_str) 유형 문자열. 보호 섹션. 개인 섹션. 데이터 http_client type ref to if_http_client. 메소드 필_WARNING 리턴 값 (상태) 유형 Zutil_cl_defs => gty_state. 엔드 클래스. 클래스 zutil_cl_rest_ws 구현. * ---------------------------------------------------------------------------------------+ * | 인스턴스 공개 방법 zutil_cl_rest_ws-> call_ws * + ------------------------------------------------------------------------------------------------------------------ * | [--->] i_url 유형 문자열 * | [--->] i_content_type 유형 문자열 (default = c_content_type_json) * | [--->] i_request_method 유형 문자열 (default = c_request_method_get) * | [--->] i_username 유형 문자열 (선택 사항) * | [--->] i_password 유형 문자열 (선택 사항) * | [--->] i_payload 유형 문자열 (선택 사항) * | [gty_state * | [Method Call_ws. 데이터 : cx_root에 대한 exref type ref. 노력하다. "이 create_by_url을 사용 하여이 클래스 사용의 특정 측면을 단순화 할 수 있습니다 http_client. cl_http_client => create_by_url (내보내기 URL = i_URL 클라이언트 importing 클라이언트 = http_client Exturetions argument_not_found = 1 plugin_not_active = 2 internal_error = 3 eloge = 4). sy-subrc <> 0 인 경우. e_state-state = fill_warning (). 반품. endif. "내 논리는 원래 사용되었지만 http_client-> request-> set_method (i_request_method)를 게시 할 수 있어야합니다. http_client-> request-> set_content_type (i_content_type). "i_username이 초기가 아니거나 i_password가 초기가 아닌 경우 인증하는 것을 잊지 마십시오. http_client-> 인증 (username = i_username password = i_password). endif. "존재하는 경우 I_PAYLOAD가 초기가 아닌 경우 페이로드를 준비하고 할당하십시오. "그 페이로드를 XSTRING으로 변환하십시오. 데이터 lv_payload_x 유형 xstring. 통화 함수 'scms_string_to_xstring'텍스트 내보내기 텍스트 = i_payload 가져 오기 버퍼 = lv_payload_x 예외 실패 = 1 기타 = 2. sy-subrc <> 0 인 경우. e_state-state = zutil_cl_defs => c_state_warning. e_state-state = '인코딩 오류!'. 반품. 또 다른. http_client-> request-> set_data (lv_payload_x). "이진 데이터 endif. endif. "요청 보내기 http_client-> send (예외 http_communication_failure = 1 http_invalid_state = 2). sy-subrc <> 0 인 경우. e_state-state = fill_warning (). 반품. endif. "응답 수신 http_client-> reception (예외 http_communication_failure = 1 http_invalid_state = 2 http_processing_failed = 3). sy-subrc <> 0 인 경우. e_state-state = fill_warning (). 반품. endif. "응답을 확인하십시오. 바라건대 JSON 응답을 되 찾을 수 있기를 바랍니다. e_response_str = http_client-> 응답-> get_cdata (). e_response_str가 초기 인 경우. e_response_str = http_client-> 응답-> get_data (). endif. e_state-state = zutil_cl_defs => c_state_success. e_state-state_text = '성공적으로 완료되었습니다.'. cx_root를 Exref로 잡으십시오. e_state-state = zutil_cl_defs => c_state_error. e_state-state_text = exref-> get_text (). 엔 트리. endmethod. * ---------------------------------------------------------------------------------------+ * | 인스턴스 비공개 방법 zutil_cl_rest_ws-> fill_warning * + ------------------------------------------------------------------------------------------------------------------------------------------------------------- | [gty_state * +-------------------------------------------------------------------------------------- 메소드 Fill_Warning. State-State = zutil_cl_defs => c_state_warning. http_client-> get_last_error (가져 오기 메시지 = data (msg) "오류 메시지). state-state_text = msg. endmethod. 엔드 클래스.
소비자 클래스 코드. 먼저 응답 구조를 풀고 상태를 확인합니다. 성공이라면 Call ID 1001의 결과에 대한 Body JSON 부품을 풀어주십시오.
클래스 zrest_cl_consumer 정의 public final 공개 생성 . 공개 섹션. 메소드 get_dateTime 상태 유형 zutil_cl_defs => gty_state dt type tzntimestp. 보호 섹션. 개인 섹션. 엔드 클래스. 클래스 zrest_cl_consumer 구현. * ---------------------------------------------------------------------------------------+ * | 인스턴스 공개 방법 zrest_cl_consumer-> get_datetime * + --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | [gty_state * | [방법 get_dateTime. "REST Web API 데이터를 소비하는 샘플 방법 : Exref Type Ref to CX_ROOT. 노력하다. "상수 : c_uname 유형 문자열 값 '개발자', c_pass 유형 문자열 값 'down1oad'. "호출 데이터 빌드 : URL 유형 문자열 값 'http : // vhcalnplci : 8000/sap/bc/rest/zrest/rest?SAP-CLIENT = 001 '. 데이터 req_stc 유형 zrest_s_request. req_stc-id = '1001'. data (req_json) = /ui2 /cl_json => serialize (데이터 내보내기 = req_stc). url = url && '& req ='&& req_json. "Call Web API New Zutil_cl_rest_ws ()-> call_ws (i_url = url i_username = c_uname i_password = c_pass 가져 오기 e_state = state e_response_str = data (json_response)). State-State eq zutil_cl_defs => c_state_success 인 경우. 데이터 : resp_stc 유형 zrest_s_response. /ui2/cl_json => deserialize (json = json_response 변경 데이터 = resp_stc). RESP_STC-State-State eq zutil_cl_defs => c_state_success 인 경우. 유형 : ty_res의 시작, datetime type tzntimestp, ty_res의 끝. 데이터 : resp_1001 유형 ty_res. /ui2/cl_json => deserialize (json = resp_stc-body 변경 데이터 = resp_1001). dt = resp_1001- 래디 턴. endif. endif. cx_root를 Exref로 잡으십시오. State-State = zutil_cl_defs => c_state_error. state-state_text = exref-> get_text (). 엔 트리. endmethod. 엔드 클래스.
그게 다야. 그런 식으로 모든 환경, 시스템을 SAP에 통합 할 수 있습니다.
도움이되기를 바랍니다.
읽어 주셔서 감사합니다.
관련된 링크들