Objective: Provides a brief introduction to REST services in general and explains the basic usage of the ABAP REST library (SAP_BASIS 7.40) in particular.
Applies to: SAP NetWeaver AS ABAP since 7.00. The SAP documentation for REST is available in AS ABAP 7.40.
Target Group: Develpers, architects, consultants, project leads and decision makers who want to gain first information on the ABAP REST library.
This blog post gives a short introduction to the new ABAP library for REST based services, which is part of ABAP 7.4. In particular in combination with the new JSON support in ABAP 7.4, it can be used writing native HTTP services directly on top of the Internet Communication Framework (ICF) following a RESTful design.
The REST library is used as a central component in the following frameworks:
It should be stressed that the REST library is a technical library and does not provide a programming, configuration or operations model on top of the ICF.
For productive business scenarios SAP recommends to use the SAP NetWeaver Gateway which provides all qualities for REST services based on the OData standard.
Note that the core SAP NetWeaver Gateway infrastructure is also directly part of the SAP NetWeaver Application Server ABAP since release 7.4.
REST is an acronym for Representational State Transfer and stands for a programming paradigm for Web applications. The REST architectural style was first introduced by Roy Fielding (Link).
The central principle of REST services is the existence of resources each of them referenced with a unique resource identifier (URI). The reading and manipulation of these resources is based on a standardized interface which is the HTTP protocol. Via the HTTP protocol, client and servers exchange and transfer representations of resources, i.e. documents conveying the information of a resource.
There is a lot of information available in the Web about that question (and the alternatives to REST, e.g. SOAP based Web Services), so only some main indicators should be mentioned here:
The ABAP REST library specific classes are located in package SREST and its subpackages (SREST_CORE, SREST_EXT, SREST_HTTP, SREST_TEST, SREST_UTIL). If you want to use the ABAP REST library, you have to declare an access usage for the corresponding package interface. Using the ABAP REST library, the focus in this blog is on developing REST services in the context of the HTTP protocol, i.e. the URI schema is http or https, the authority identifies an ABAP application server, the SAP web dispatcher or some network intermediate (e.g. reverse proxy, which is set up to forward a request to an ABAP application server). The path consists of the base path (defined in the ABAP Internet Communication Framework (ICF) for a REST service's handler class) and the resource path, used by a REST application service to identify the requested resource.
This picture gives a rough overview on the control flow when processing a REST request within an ABAP application server.
These are the 3 main processing steps (see picture above):
Used interfaces and classes of an ABAP REST service implementation:
All interfaces and classes, their usage and background information is available via SAP help (SAP Basis Release 7.40).
Especially the REST Programming Tutorial is of interest for people to have a first hand on ABAP REST programming.
This picture shows the sequence of class usage on the REST server side:
The REST example used in this blog is using parts of the well-known SAP Flight sample data model. In this example, the resources are "flight" resources made available to REST clients stored in the database table SFLIGHT.
The REST application class named ZCL_SCN_BLOG_FLIGHT_APP is dervied from the ABAP library class CL_REST_HTTP_HANDLER. This REST service class inherits especially the interface method IF_REST_APPLICATION~GET_ROOT_HANDLER. Within this method, at least one URI template gets attached to a REST handler class (multiple attachments are possible depending on the number of supported URIs and used classes). The handler class is named ZCL_SCN_BLOG_FLIGHT_RESOURCE in this example (for its implementation see below).
This is the implementation of method IF_REST_APPLICATION~GET_ROOT_HANDLER in the REST application class ZCL_REST_FLIGHT_APPL:
method if_rest_application~get_root_handler.
data(lo_router) = new cl_rest_router( ).
lo_router->attach( iv_template = '/flights' iv_handler_class = 'ZCL_SCN_BLOG_FLIGHT_RESOURCE' ).
lo_router->attach( iv_template = '/flights.{format}' iv_handler_class = 'ZCL_SCN_BLOG_FLIGHT_RESOURCE' ).
lo_router->attach( iv_template = '/flights/{carrid}' iv_handler_class = 'ZCL_SCN_BLOG_FLIGHT_RESOURCE' ).
lo_router->attach( iv_template = '/flights/{carrid}.{format}' iv_handler_class = 'ZCL_SCN_BLOG_FLIGHT_RESOURCE' ).
lo_router->attach( iv_template = '/flights/{carrid}/{connid}' iv_handler_class = 'ZCL_SCN_BLOG_FLIGHT_RESOURCE' ).
lo_router->attach( iv_template = '/flights/{carrid}/{connid}.{format}' iv_handler_class = 'ZCL_SCN_BLOG_FLIGHT_RESOURCE' ).
lo_router->attach( iv_template = '/flights/{carrid}/{connid}/{fldate}' iv_handler_class = 'ZCL_SCN_BLOG_FLIGHT_RESOURCE' ).
lo_router->attach( iv_template = '/flights/{carrid}/{connid}/{fldate}.{format}' iv_handler_class = 'ZCL_SCN_BLOG_FLIGHT_RESOURCE' ).
ro_root_handler = lo_router.
endmethod.
In this code example, multiple URL templates are attached to one and the same resource class ZCL_SCN_BLOG_FLIGHT_RESOURCE (which is not mandatory). For the details on the definition on URI templates, you may refer to the SAP documentation. In this blog only an example is given for the routing.
Example (Routing):
Assume that the URL 'http://ldai3yi3.wdf.sap.corp:50034/sap/bc/rest/scn_test/flights/LH/0400.json?sap-client=000' is called with the HTTP GET method.For the correct routing of the request to the method IF_REST_RESOURCE~GET in class ZCL_SCN_BLOG_FLIGHT_RESOURCE, the class ZCL_SCN_BLOG_FLIGHT_APP has to be entered in the ICF as handler class (e.g. in the ICF node 'SCN_SAMPLE'). The URI-attributes 'carrid' is set to value 'LH', the attribute 'connid' is set to value '400' and the 'format' attribute is set to 'json'. All these attributes get set by the REST framework and are available in the request object in the resource processor class ZCL_SCN_BLOG_FLIGHT_RESOURCE (defined as data members in its base class CL_REST_RESOURCE).
In this example, the class representing the "flight" resource is named ZCL_SCN_BLOG_FLIGHT_RESOURCE and is derived from the REST library class CL_REST_RESOURCE. It implements the methods of interface IF_REST_RESOURCE. The interface methods GET and OPTIONS are supported, i.e. this method is implemented in the resource class (note: methods not implemented will hit the default implementation of CL_REST_RESOURCE and return a HTTP 405 return code: "HTTP method '...' not supported").
This is the implementation of method IF_REST_RESOURCE~GET in class ZCL_SCN_BLOG_FLIGHT_RESOURCE:
method if_rest_resource~get.
data: lt_flight type table of sflight.
data(lo_entity) = mo_response->create_entity( ).
data(lv_carrid) = mo_request->get_uri_attribute( iv_name = 'carrid' ).
data(lv_connid) = mo_request->get_uri_attribute( iv_name = 'connid' ).
data(lv_fldate) = mo_request->get_uri_attribute( iv_name = 'fldate' ).
if ( lv_fldate is not initial ).
select * from sflight into table lt_flight
where carrid = lv_carrid and connid = lv_connid and fldate = lv_fldate.
elseif ( lv_connid is not initial ).
select * from sflight into table lt_flight
where carrid = lv_carrid and connid = lv_connid.
elseif ( lv_carrid is not initial ).
select * from sflight into table lt_flight
where carrid = lv_carrid.
else.
select * from sflight into table lt_flight.
endif.
data(lv_format) = mo_request->get_uri_attribute( iv_name = 'format' ).
if ( lv_format = 'json' or lv_format is initial ).
" Transform data to JSON
data(lo_json_writer) = cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ).
call transformation id source itab = lt_flight result xml lo_json_writer.
lo_entity->set_content_type( if_rest_media_type=>gc_appl_json ).
lo_entity->set_binary_data( lo_json_writer->get_output( ) ).
elseif ( lv_format = 'xml' ).
" Transform data to XML
call transformation id source itab = lt_flight result xml data(lv_xml).
lo_entity->set_content_type( if_rest_media_type=>gc_appl_xml ).
lo_entity->set_binary_data( lv_xml ).
elseif ( lv_format = 'atom' ).
" Transform data to Atom
data: ls_feed type if_atom_types=>feed_s,
ls_entry type if_atom_types=>entry_s.
ls_feed-id-uri = 'http://www.sap.com'.
get time stamp field ls_feed-updated-datetime.
loop at lt_flight assigning field-symbol(<f>).
ls_entry-title-text = | { <f>-carrid }-{ <f>-connid }|.
convert date <f>-fldate
into time stamp ls_entry-updated-datetime time zone 'UTC'.
ls_entry-title-type = if_atom_types=>gc_content_text.
append ls_entry to ls_feed-entries.
endloop.
data(lo_provider) = new cl_atom_feed_prov( ).
lo_provider->set_feed( ls_feed ).
lo_provider->write_to( lo_entity ).
endif.
mo_response->set_status( cl_rest_status_code=>gc_success_ok ).
endmethod.
Brief description of the implementation:
This is the implementation of method IF_REST_RESOURCE~OPTIONS in class ZCL_SCN_BLOG_FLIGHT_RESOURCE:
method if_rest_resource~options.
mo_response->set_header_field( iv_name = if_http_header_fields=>allow iv_value = 'OPTIONS,GET' ).
mo_response->set_status( cl_rest_status_code=>gc_success_no_content ).
endmethod.
Brief description of the implementation:
Beside the basic functionality of a REST service mentioned above, there are additional features integrated into the ABAP REST library (which are only mentioned in this blog without detailed explanation (for more in depth information refer to the SAP documentation):
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
25 | |
5 | |
4 | |
2 | |
2 | |
2 | |
2 | |
2 | |
2 | |
1 |