replace
ro_client_proxy ?= /iwbep/cl_cp_client_proxy=>create_rest_remote_proxy(
with
mo_client_proxy_int ?= /iwbep/cl_cp_client_proxy_fact=>create_rest_remote_proxy(
Please note that this step is entirely optional but highly recommended, if you want to skip this section go directly to "Consuming Service via CP" heading
The interface for structure types and constants
The client proxy model
The client to consume the service
Note: when copying the code in this blog replace the suffix ZAF_ with your own one
TYPES:
BEGIN OF tys_category,
id TYPE i,
name TYPE string,
END OF tys_category,
BEGIN OF tys_tag,
id TYPE i,
name TYPE string,
END OF tys_tag,
BEGIN OF tys_pet,
id TYPE i,
name TYPE string,
category TYPE tys_category,
photo_urls TYPE STANDARD TABLE OF string WITH DEFAULT KEY,
tags TYPE STANDARD TABLE OF tys_tag WITH DEFAULT KEY,
status TYPE string,
END OF tys_pet.
<Pet>
<category>
<id>0</id>
<name>Pug</name>
</category>
<id>3</id>
<name>doggie</name>
<photoUrls>
<photoUrl>axyz.in</photoUrl>
<photoUrl>axyz.in</photoUrl>
<photoUrl>axyz.in</photoUrl>
</photoUrls>
<status>available</status>
<tags>
<tag>
<id>22</id>
<name>dog</name>
</tag>
</tags>
</Pet>
BEGIN OF gcs_resource_names,
pets TYPE /iwbep/if_v4_rest_types=>ty_internal_name VALUE `PETS`,
pet_id TYPE /iwbep/if_v4_rest_types=>ty_internal_name VALUE `PET_ID`,
pet_id_name_status TYPE /iwbep/if_v4_rest_types=>ty_internal_name VALUE `PET_ID_NAME_STATUS`,
END OF gcs_resource_names,
BEGIN OF gcs_resource_paths,
pets TYPE string VALUE `/pet`,
pet_id TYPE string VALUE `/pet/{id}`,
pet_id_name_status TYPE string VALUE `/pet/{id}?name={name}&status={status}`,
END OF gcs_resource_paths.
CLASS zaf_cl_rest_petstore_model DEFINITION
PUBLIC
INHERITING FROM /iwbep/cl_v4_abs_model_prov
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS /iwbep/if_v4_mp_basic_rest~define REDEFINITION.
PRIVATE SECTION.
"! <p class="shorttext synchronized" lang="en">Define the structure type and resources for Pet</p>
"!
"! @parameter io_model | <p class="shorttext synchronized" lang="en">Proxy model</p>
"! @raising /iwbep/cx_gateway | <p class="shorttext synchronized" lang="en">Gateway exception</p>
METHODS define_pet
IMPORTING
io_model TYPE REF TO /iwbep/if_v4_rest_model
RAISING
/iwbep/cx_gateway .
ENDCLASS.
CLASS zaf_cl_rest_petstore_model IMPLEMENTATION.
METHOD /iwbep/if_v4_mp_basic_rest~define.
define_pet( CAST /iwbep/if_v4_rest_model( io_model ) ).
ENDMETHOD.
METHOD define_pet.
DATA:
ls_data_container_pet TYPE zaf_if_petstore_types=>tys_pet,
ls_data_container_tag TYPE zaf_if_petstore_types=>tys_tag,
ls_data_container_category TYPE zaf_if_petstore_types=>tys_category,
lo_structured_type TYPE REF TO /iwbep/if_v4_rest_struc_type,
lo_resource TYPE REF TO /iwbep/if_v4_rest_resource,
lo_operation TYPE REF TO /iwbep/if_v4_rest_operation.
*Define Category
lo_structured_type = io_model->create_struct_type_by_struct(
iv_name = zaf_if_petstore_types=>gcs_internal_struct_type_names-category
is_structure = ls_data_container_category
iv_do_gen_prim_props = abap_true ).
lo_structured_type->camelcase_lower_prim_prp_names( ).
*Define Tag
lo_structured_type = io_model->create_struct_type_by_struct(
iv_name = zaf_if_petstore_types=>gcs_internal_struct_type_names-tag
is_structure = ls_data_container_tag
iv_do_gen_prim_props = abap_true ).
lo_structured_type->camelcase_lower_prim_prp_names( ).
*Define Pet
lo_structured_type = io_model->create_struct_type_by_struct(
iv_name = zaf_if_petstore_types=>gcs_internal_struct_type_names-pet
is_structure = ls_data_container_pet
iv_do_gen_prim_props = abap_true
iv_do_gen_prim_prop_colls = abap_true ).
lo_structured_type->camelcase_lower_prim_prp_names( ).
lo_structured_type->create_structured_property( 'CATEGORY'
)->set_external_name( 'category'
)->set_structured_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-category ).
lo_structured_type->create_structured_property( 'TAGS'
)->set_external_name( 'tags'
)->set_structured_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-tag )->set_is_collection( ).
lo_resource = io_model->create_resource( iv_name = zaf_if_petstore_types=>gcs_resource_names-pet_id
iv_path_template = zaf_if_petstore_types=>gcs_resource_paths-pet_id ).
lo_resource->set_path_params_struct_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-pet
)->create_operation( /iwbep/if_v4_rest_types=>gcs_http_method-get
)->create_response_body(
)->set_structured_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-pet ).
*Delete
lo_resource->set_path_params_struct_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-pet
)->create_operation( /iwbep/if_v4_rest_types=>gcs_http_method-delete
)->create_response_body( ).
*Update Status and Name
io_model->create_resource( iv_name = zaf_if_petstore_types=>gcs_resource_names-pet_id_name_status
iv_path_template = zaf_if_petstore_types=>gcs_resource_paths-pet_id_name_status
)->set_path_params_struct_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-pet
)->create_operation( /iwbep/if_v4_rest_types=>gcs_http_method-post
)->create_response_body(
)->set_structured_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-pet ).
lo_resource = io_model->create_resource( iv_name = zaf_if_petstore_types=>gcs_resource_names-pets
iv_path_template = zaf_if_petstore_types=>gcs_resource_paths-pets ).
*Create
lo_operation = lo_resource->create_operation( /iwbep/if_v4_rest_types=>gcs_http_method-post ).
lo_operation->create_request_body(
)->set_structured_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-pet ).
lo_operation->create_response_body(
)->set_structured_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-pet ).
*Update with put
lo_operation = lo_resource->create_operation( /iwbep/if_v4_rest_types=>gcs_http_method-put ).
lo_operation->create_request_body(
)->set_structured_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-pet ).
lo_operation->create_response_body(
)->set_structured_type( zaf_if_petstore_types=>gcs_internal_struct_type_names-pet ).
END METHOD.
END CLASS.
CLASS zaf_cl_rest_petstore_client DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS CONSTRUCTOR raising /iwbep/cx_gateway.
"! <p class="shorttext synchronized" lang="en">Create a Pet</p>
"! @parameter is_pet | <p class="shorttext synchronized" lang="en">typed structure containing create data</p>
"! @parameter rs_pet | <p class="shorttext synchronized" lang="en">typed structure containing response data from server </p>
"! @raising /iwbep/cx_gateway | <p class="shorttext synchronized" lang="en"></p>
METHODS pet_create
IMPORTING
is_pet TYPE zaf_if_petstore_types=>tys_pet
RETURNING
VALUE(rs_pet) TYPE zaf_if_petstore_types=>tys_pet
RAISING
/iwbep/cx_gateway.
"! <p class="shorttext synchronized" lang="en">Delete a Pet with supplied id</p>
"! This method does not return a json response body which can be serialized in to abap structure, so the http code is returned.
"! @parameter iv_id | <p class="shorttext synchronized" lang="en"></p>
"! @parameter rv_http_status_code | <p class="shorttext synchronized" lang="en"></p>
"! @raising /iwbep/cx_gateway | <p class="shorttext synchronized" lang="en"></p>
METHODS pet_delete
IMPORTING
iv_id TYPE i
RETURNING
VALUE(rv_http_status_code) TYPE i
RAISING
/iwbep/cx_gateway.
"! <p class="shorttext synchronized" lang="en">Get a pet with supplied id</p>
"!
"! @parameter iv_id | <p class="shorttext synchronized" lang="en">The id of the pet</p>
"! @parameter rs_pet | <p class="shorttext synchronized" lang="en">Returned pet as ABAP structure, complete with deep fields.</p>
"! @raising /iwbep/cx_gateway | <p class="shorttext synchronized" lang="en"></p>
METHODS pet_read_by_id
IMPORTING
iv_id TYPE i
RETURNING
VALUE(rs_pet) TYPE zaf_if_petstore_types=>tys_pet
RAISING
/iwbep/cx_gateway.
"! <p class="shorttext synchronized" lang="en">Update a pet using PUT</p>
"! @parameter is_pet | <p class="shorttext synchronized" lang="en">typed structure containing update data</p>
"! @parameter rs_pet | <p class="shorttext synchronized" lang="en">typed structure containing response data from server </p>
"! @raising /iwbep/cx_gateway | <p class="shorttext synchronized" lang="en"></p>
METHODS pet_update
IMPORTING
is_pet TYPE zaf_if_petstore_types=>tys_pet
RETURNING
VALUE(rs_pet) TYPE zaf_if_petstore_types=>tys_pet
RAISING
/iwbep/cx_gateway.
"! <p class="shorttext synchronized" lang="en">Update the name and status of the pet having the supplied ID</p>
"! The variables to be updated are sent as query parameters. The request type is POST
"! @parameter iv_id | <p class="shorttext synchronized" lang="en">ID of the pet that is to be updated.</p>
"! @parameter iv_name | <p class="shorttext synchronized" lang="en">new name for the pet</p>
"! @parameter iv_status | <p class="shorttext synchronized" lang="en">new status for the pet</p>
"! @parameter rs_pet | <p class="shorttext synchronized" lang="en">Updated pet </p>
"! @raising /iwbep/cx_gateway | <p class="shorttext synchronized" lang="en"></p>
METHODS pet_update_name_and_status
IMPORTING
iv_id TYPE i
iv_name TYPE zaf_if_petstore_types=>tys_pet-name
iv_status TYPE zaf_if_petstore_types=>tys_pet-status
RETURNING
VALUE(rs_pet) TYPE zaf_if_petstore_types=>tys_pet
RAISING
/iwbep/cx_gateway.
PRIVATE SECTION.
DATA: mo_client_proxy TYPE REF TO /iwbep/if_cp_client_proxy_rest,
mo_http_client TYPE REF TO if_http_client.
METHODS create_client_proxy
RETURNING
VALUE(ro_client_proxy) TYPE REF TO /iwbep/if_cp_client_proxy_rest
RAISING
/iwbep/cx_gateway.
ENDCLASS.
CLASS zaf_cl_rest_petstore_client IMPLEMENTATION.
METHOD constructor.
mo_client_proxy = create_client_proxy( ).
ENDMETHOD.
METHOD pet_create.
*https://petstore3.swagger.io/api/v3/pet POST
mo_client_proxy->create_resource( zaf_if_petstore_types=>gcs_resource_names-pets
)->create_request( /iwbep/if_v4_rest_types=>gcs_http_method-post
)->set_body_data( is_pet
)->execute(
)->get_body_data( IMPORTING ea_body_data = rs_pet ).
ENDMETHOD.
METHOD pet_delete.
*https://petstore3.swagger.io/api/v3/pet DELETE
DATA ls_key TYPE zaf_if_petstore_types=>tys_pet.
rv_http_status_code = mo_client_proxy->create_resource( zaf_if_petstore_types=>gcs_resource_names pet_id
)->set_path_template_parameters( ls_key
)->create_request( /iwbep/if_v4_rest_types=>gcs_http_method-delete
)->execute( )->get_http_status_code( ).
ENDMETHOD.
METHOD pet_read_by_id.
*https://petstore3.swagger.io/api/v3/pet/{id} GET
mo_client_proxy->create_resource( zaf_if_petstore_types=>gcs_resource_names-pet_id
)->set_path_template_parameters( VALUE zaf_if_petstore_types=>tys_pet( id = iv_id )
)->create_request( /iwbep/if_v4_rest_types=>gcs_http_method-get
)->execute(
)->get_body_data( IMPORTING ea_body_data = rs_pet ).
ENDMETHOD.
METHOD pet_update.
*https://petstore3.swagger.io/api/v3/pet PUT
mo_client_proxy->create_resource( zaf_if_petstore_types=>gcs_resource_names-pets
)->create_request( /iwbep/if_v4_rest_types=>gcs_http_method-put
)->set_body_data( is_pet
)->execute(
)->get_body_data( IMPORTING ea_body_data = rs_pet ).
ENDMETHOD.
METHOD pet_update_name_and_status.
*https://petstore3.swagger.io/api/v3/pet/{id}?name={name}&status={status} POST
mo_client_proxy->create_resource( zaf_if_petstore_types=>gcs_resource_names-pet_id_name_status
)->set_path_template_parameters(
VALUE zaf_if_petstore_types=>tys_pet(
id = iv_id
name = iv_name
status = iv_status )
)->create_request( /iwbep/if_v4_rest_types=>gcs_http_method-post
)->execute(
)->get_body_data( IMPORTING ea_body_data = rs_pet ).
ENDMETHOD.
METHOD create_client_proxy.
DATA:
ls_proxy_model_key TYPE /iwbep/if_cp_registry_types=>ty_s_proxy_model_key,
lv_error_text TYPE string.
cl_http_client=>create_by_url(
EXPORTING
url = 'https://petstore3.swagger.io'
IMPORTING
client = mo_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 ).
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO lv_error_text.
RAISE EXCEPTION TYPE lx_rest_json_pl
EXPORTING
iv_error_text = lv_error_text.
ENDIF.
"Proxy model defined in ZAF_CL_REST_PETSTORE_MODEL
ls_proxy_model_key = VALUE #( repository_id = /iwbep/if_cp_registry_types=>gcs_repository_id-default
proxy_model_id = 'ZAF_REST_PETSTORE'
proxy_model_version = 0003 ).
ro_client_proxy ?= /iwbep/cl_cp_client_proxy=>create_rest_remote_proxy(
is_proxy_model_key = ls_proxy_model_key
io_http_client = mo_http_client
iv_do_fetch_csrf_token = abap_false
iv_relative_service_root = '/api/v3').
ENDMETHOD.
Proxy Model ID | *You can choose any value e.g ZAF_REST_PETSTORE |
Version | 1 |
Model Provider Class | *Enter name of your proxy model class |
Description | *Enter any description |
Package | $TMP |
CLASS zaf_cl_petstore_test DEFINITION DEFERRED.
class zaf_cl_rest_petstore_client definition local friends
zaf_cl_petstore_test.
CLASS zaf_cl_petstore_test DEFINITION
FINAL
FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.
PUBLIC SECTION.
METHODS:
pet_operations FOR TESTING RAISING /iwbep/cx_gateway.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO zaf_cl_rest_petstore_client.
METHODS: setup RAISING /iwbep/cx_gateway.
ENDCLASS.
CLASS zaf_cl_petstore_test IMPLEMENTATION.
METHOD pet_operations.
DATA:
ls_payload TYPE zaf_if_petstore_types=>tys_pet,
ls_response_exp TYPE zaf_if_petstore_types=>tys_pet,
ls_response_act TYPE zaf_if_petstore_types=>tys_pet,
ls_category TYPE zaf_if_petstore_types=>tys_category,
lv_http_status_code TYPE string,
lv_id TYPE i,
lx_gateway TYPE REF TO /iwbep/cx_gateway.
*CREATE
ls_category = VALUE #(
id = 20
name = 'Persian' ).
ls_payload = VALUE #(
id = 34
name = 'Cat'
status = 'Brand New'
category = ls_category
photo_urls = VALUE #( ( |url_1| ) ) ).
ls_response_exp = ls_payload.
ls_response_act = mo_cut->pet_create( ls_payload ).
"Then the expected pet data should be returned.
cl_abap_unit_assert=>assert_equals( exp = ls_response_exp
act = ls_response_act ).
CLEAR ls_response_act.
*READ BY ID
"When we make a get request for a pet with this id.
lv_id = 34.
ls_response_act = mo_cut->pet_read_by_id( lv_id ).
"Then the expected pet data should be returned.
cl_abap_unit_assert=>assert_equals( exp = ls_response_exp
act = ls_response_act ).
CLEAR ls_response_act.
*UPDATE NAME AND STATUS
ls_response_act = mo_cut->pet_update_name_and_status(
iv_id = 34
iv_name = 'new_name'
iv_status = 'new_status' ).
ls_response_exp-name = 'new_name'.
ls_response_exp-status = 'new_status'.
cl_abap_unit_assert=>assert_equals( exp = ls_response_exp
act = ls_response_act ).
*UPDATE
ls_payload-name = 'Schrodingers Cat'.
ls_payload-status = 'Dead and Alive'.
ls_payload-category = VALUE #(
id = 21
name = 'Mystery Kitty' ).
ls_response_exp = ls_payload.
ls_response_act = mo_cut->pet_update( ls_payload ).
cl_abap_unit_assert=>assert_equals( exp = ls_response_exp
act = ls_response_act ).
*DELETE
lv_http_status_code = mo_cut->pet_delete( 4 ).
"the expected pet data should be returned.
cl_abap_unit_assert=>assert_equals( exp = 200
act = lv_http_status_code ).
ENDMETHOD.
METHOD setup.
mo_cut = NEW zaf_cl_rest_petstore_client( ).
ENDMETHOD.
ENDCLASS.
You may also follow the RESTful ABAP Programming Tag for more content and checkout these community links:
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
13 | |
12 | |
11 | |
11 | |
9 | |
9 | |
9 | |
8 | |
7 | |
6 |