Create RESTful APIs in ABAP Tools
Create RESTful APIs in ABAP Tools
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Document History © 2020 SAP AG or an SAP affiliate company. All rights reserved. 2
Prerequisites
This documentation belongs to ABAP Development Tools (ADT) and refers to the range of functions that have
been shipped as part of the standard delivery for:
• SAP NetWeaver 7.40 SP 2 and higher
• Application Server ABAP 7.53 and higher
SAP Cloud Platform ABAP Environment is currently not supported.
How To... Create RESTful APIs and consume them in the ABAP Development Tools
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Table of Contents © 2020 SAP AG or an SAP affiliate company. All rights reserved. 4
1 Introduction
1.1 Business Scenario
This tutorial shows you how to implement a simple RESTful API in the ABAP back end and how to consume it from
the Java client.
It follows the implementation of a resource controller for getting data from a flight resource. This RESTful API
allows an Eclipse client to read and display existing flight data from the Application Server ABAP (AS ABAP).
Figure 1: RESTful API that reads existing flight data from the ABAP server and consumes it on the Eclipse client
ABAP Server:
• Creating server-side resource controllers that are responsible for handling the API calls
• Serializing and deserializing XML data through simple transformations
• Creating application classes. These make it possible to call resource controllers from the client
• Adding the new API to the discovery API document
Eclipse Client:
• Creating a new Eclipse plug-in
• Calling the API from the client
• Deserializing the response data from the server using content handlers
• Writing integration tests for the RESTful API
1.4 Prerequisites
• Eclipse development platform: Eclipse or NetWeaver Developer Studio for Java client coding
• Eclipse target platform: Latest version of ABAP Development Tools
• AS ABAP Server: SAP NetWeaver 7.40 SP 2 or higher
• ABAP Development Tools 2.19 or higher
How To... Create RESTful APIs and consume them in the ABAP Development Tools
1.6 Glossary
In this document, the following terms are used:
Term Definition
Hypermedia as the Engine of Application State Constraint of the REST application architecture
(HATEOAS)
Representational State Transfer (REST) Architectural style for distributed systems such as the World
Wide Web
Resource application Domain-specific router class that is identified using a URI - for
example, a resource path. Each resource application is
implemented as a BADI implementation. The relevant router
class for a given URI is identified through filter values.
Resource controller Instance that is responsible for creating, reading, updating, and
deleting REST resources
RESTful API API that allows access by a representational state transfer
REST resource Resources that are identified in requests - for example, using
URIs in Web-based REST systems.
1.7 Example
For the data transfer between the client, ABAP server, and database, a custom XML format is used that is
produced through a simple transformation.
Figure 2: Interaction between the client, ABAP server, and database to display flight information on the Eclipse client
The RFC handler coordinates the data transfer between the client, ABAP server, and the database. It dispatches
the client requests to a domain-specific router called resource application. Within the resource application,
requests are delegated to single resource controllers for each single resource.
NOTE
In this tutorial, flights in the table SFLIGHT are exposed as a resource at the absolute path:
/mycompany/mydomain/restflights/##/flights/{carrier_id}/{connection_id}/{flight_date}
In all examples, when you create your individual resources or ABAP development objects, replace ## in the names
with an abbreviation. Note that the name is not longer than 7 characters.
How To... Create RESTful APIs and consume them in the ABAP Development Tools
2.1 Prerequisites
If you work with SAP NetWeaver 7.40 SP2, you need to implement SAP Note 1774777 in advance.
To access your implemented URI-resources, you need to register these URIs in the authorization object
S_ADT_RES. Otherwise, you will get responses with the HTTP-Code 403 Forbidden in [Link].
If you need further assistance for access permission, contact your SAP system administrator.
NOTE
The base class CL_ADT_REST_RESOURCE provides default implementations for the methods GET, POST, PUT,
and DELETE, that is, a subset of the methods defined in HTTP. For implementing read access of a resource, you
have to override the GET method.
[Link] Example
Definition part of the ABAP class:
class Z_CL_##_SFLIGHT_RES_FLIGHT definition
public
inheriting from CL_ADT_REST_RESOURCE
final
create public .
public section.
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 7
constants CO_ROOT_NAME type STRING value 'FLIGHT_DATA'. "#EC NOTEXT
protected section.
private section.
" read flight key from URI
methods GET_FLIGHT_KEY_FROM_URI
importing
REQUEST type ref to IF_ADT_REST_REQUEST
exporting
CARRIER_ID type S_CARR_ID
CONNECTION_ID type S_CONN_ID
FLIGHT_DATE type S_DATE
raising
CX_ADT_REST.
endclass.
<?[Link] simple?>
<tt:transform xmlns:tt="[Link]
xmlns:ddic="[Link]
xmlns:flights="[Link]
<tt:template>
<flights:flight tt:extensible="deep" tt:ref="flight_data">
<tt:attribute name="carrierid" value-ref="carrid"/>
<tt:attribute name="connectionid" value-ref="connid"/>
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 8
<tt:attribute name="date" value-ref="fldate"/>
<tt:attribute name="price" value-ref="price"/>
<tt:attribute name="currency" value-ref="currency"/>
<tt:attribute name="planetype" value-ref="planetype"/>
<tt:attribute name="seatsmax" value-ref="seatsmax"/>
<tt:attribute name="seatsoccupied" value-ref="seatsocc"/>
</flights:flight>
</tt:template>
</tt:transform>
[Link] Example
In the code snippet below, you can see the GET method that accesses the URI segment parameters. If the
parameter exists, the corresponding value is returned; if not, the result is an empty character field equivalent to
space. If the existence of a parameter is obligatory, you can call the method using the parameter MANDATORY =
ABAP_TRUE.
CLASS Z_CL_##_SFLIGHT_RES_FLIGHT IMPLEMENTATION.
method GET.
GET_FLIGHT_KEY_FROM_URI(
exporting
REQUEST = REQUEST
importing
CARRIER_ID = CARRIER_ID
CONNECTION_ID = CONNECTION_ID
FLIGHT_DATE = FLIGHT_DATE ).
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 9
if SY-SUBRC = 4.
raise exception type CX_ADT_RES_NOT_FOUND.
else.
" Get appropriate content handler
" Set response content
RESPONSE->SET_BODY_DATA( CONTENT_HANDLER = GET_CONTENT_HANDLER( )
DATA = WA_FLIGHT ).
endif.
endmethod.
method GET_CONTENT_HANDLER.
RESULT = CL_ADT_REST_CNT_HDL_FACTORY=>GET_INSTANCE( )-
>GET_HANDLER_FOR_XML_USING_ST(
exporting
ST_NAME = CO_ST_NAME
ROOT_NAME = CO_ROOT_NAME ).
endmethod.
method GET_FLIGHT_KEY_FROM_URI.
" Access resource id
REQUEST->GET_URI_ATTRIBUTE(
exporting
NAME = 'carrier_id'
MANDATORY = ABAP_TRUE
importing
VALUE = CARRIER_ID ).
REQUEST->GET_URI_ATTRIBUTE(
exporting
NAME = 'connection_id'
MANDATORY = ABAP_TRUE
importing
VALUE = CONNECTION_ID ).
REQUEST->GET_URI_ATTRIBUTE(
exporting
NAME = 'flight_date'
MANDATORY = ABAP_TRUE
importing
VALUE = FLIGHT_DATE ).
endmethod.
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 10
ENDCLASS.
NOTE
In the example, a generic content handler class is used to call a simple transformation as a content handler (see
method GET_CONTENT_HANDLER).
public section.
methods:
IF_ADT_REST_RFC_APPLICATION~GET_STATIC_URI_PATH redefinition.
protected section.
methods:
GET_APPLICATION_TITLE redefinition ,
REGISTER_RESOURCES redefinition.
private section.
endclass.
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 11
method GET_APPLICATION_TITLE.
RESULT = 'Flights'.
endmethod.
method REGISTER_RESOURCES.
COLLECTION = REGISTRY->REGISTER_DISCOVERABLE_RESOURCE(
exporting
URL = '/restflights/##/flights'
HANDLER_CLASS = 'Z_CL_##_SFLIGHT_RES_FLIGHT_COL' "Handler class is just used
for example
DESCRIPTION = 'Flights'
CATEGORY_SCHEME =
'[Link]
CATEGORY_TERM = 'flights' ).
COLLECTION->REGISTER_DISC_RES_W_TEMPLATE(
exporting
RELATION =
'[Link]
TEMPLATE =
'/restflights/##/flights/{carrier_id}/{connection_id}/{flight_date}'
DESCRIPTION = 'Flight Example'
TYPE = 'application/xml'
HANDLER_CLASS = Z_CL_##_SFLIGHT_RES_FLIGHT=>CO_CLASS_NAME
).
endmethod.
method IF_ADT_REST_RFC_APPLICATION~GET_STATIC_URI_PATH.
result = '/mycompany/mydomain'.
endmethod.
endclass.
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 12
2.3.3 Creating an Enhancement Implementation
Caution
The following steps may have an impact on existing registrations that are used productively!
Do not activate the implementation until it is explicitly mentioned in the tutorial.
1. In ABAP Development Tools in Eclipse, run the Open ABAP Development Object functionality by shortcut
CTRL SHIFT A.
2. Open the enhancement spot SADT_REST_RFC_APPLICATION.
3. In the left panel, expand the node BADI_ADT_REST_RFC_APPLICATION.
4. Select the node Implementations.
5. In the context menu, choose Create BAdI Implementation.
6. In the popup window, choose the Create button to define the enhancement implementation.
7. Enter the Name and Description and trigger the creation:
Field Value
8. In the modal dialog screen for the package name, select the button Local Object.
9. Select the created enhancement implementation and double-click.
10. In the creation dialog BAdI Implementation, enter the following data:
Field Value
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 13
2.3.4 Assigning Filter Values to the Enhancement
Implementation
1. In the enhancement implementation editor, expand the node SFLIGHT_RESOURCE_APPLICATION in the
left panel.
2. Double-click the button Filter Val.
3. Toggle to the edit mode.
4. In the toolbar, press the Create Filter Combination button.
5. Select the line below Combination 1.
6. In the toolbar, choose the button Filt. Val to change the filter values.
7. In the following dialog, enter:
Field Value
Filter STATIC_URI_PATH
Comparator 2 CP
Value 2 /mycompany/mydomain/restflights/##/*
NOTE
The length of the filter value string must not exceed 40 characters! Otherwise, an error message is
displayed.
9. Confirm with the OK button.
10. In ABAP Development Tools, refresh the class Z_CL_##_SFLIGHT_RES_APP and remove the created
interface definition. Afterwards, activate the class.
11. Check if the BAdI Implementation is still consistent.
12. Activate the enhancement implementation.
13. Switch back to Display mode.
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 14
[Link] Procedure
1. In ABAP Development Tools in Eclipse, run the Open ABAP Development Object functionality using the
shortcut CTRL SHIFT A.
2. Open the enhancement spot SADT_REST_RFC_APPLICATION.
3. In the left panel, expand the node BADI_ADT_DISCOVERY_PROVIDER.
4. Select node Implementations.
5. In the context menu, choose Create BAdI Implementation.
Field Value
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 15
7. In the following dialog, enter:
Field Value
Filter URI
Comparator 1 =
Value 1 /mycompany/discovery
NOTE
The length of the filter value string must not exceed 40 characters! Otherwise, an error message is
displayed.
14. Confirm with the OK button.
15. Check for syntax errors.
16. Activate the enhancement implementation.
17. Switch back to Display mode.
[Link] Prerequisites
To implement your own URIs for your own discovery, you have to contact your SAP system administrator in order
to get access permission.
If you want to access a resource without access permission, you can use the existing discovery /sap/bc/adt
which is provided by SAP. In this case, you can continue the tutorial at chapter 3 Tutorial for Consuming REST
Resources in the Eclipse Client.
Example
Code example for the created Z_CL_##_DISCOVERY_RES_APP class:
class Z_CL_##_DISCOVERY_RES_APP definition
public
inheriting from CL_ADT_RES_APP_BASE
final
create public .
public section.
methods IF_ADT_REST_RFC_APPLICATION~GET_STATIC_URI_PATH
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 16
redefinition .
protected section.
methods:
FILL_ROUTER redefinition.
private section.
endclass.
method FILL_ROUTER.
ROUTER->ATTACH( IV_TEMPLATE = '/discovery' IV_HANDLER_CLASS =
CL_ADT_RES_DISCOVERY=>CO_CLASS_NAME ).
endmethod.
method IF_ADT_REST_RFC_APPLICATION~GET_STATIC_URI_PATH.
RESULT = '/mycompany'.
endmethod.
endclass.
Caution
The following steps may have an impact on existing registrations that are used productively!
Do not activate the implementation until it is explicitly mentioned in the tutorial.
1. In ABAP Development Tools in Eclipse, run the Open ABAP Development Object functionality using the
shortcut CTRL SHIFT A.
2. Open the enhancement spot SADT_REST_RFC_APPLICATION.
3. In the left panel of the tree, expand the tree for BADI_ADT_REST_RFC_APPLICATION.
4. Select the node Implementations.
5. In the context menu, choose Create BAdI Implementation.
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Creating Resources on the AS ABAP © 2020 SAP AG or an SAP affiliate company. All rights reserved. 17
4. In the popup window, select the Z##_SFLIGHT_TUTORIAL enhancement implementation.
5. Confirm the selection.
6. Add a new BAdI implementation.
Enter the following data:
Field Value
Field Value
Value 1 /mycompany/discovery
Comparator 1 =
Filter STATIC_URI_PATH
NOTE
The length of the filter value string must not exceed 40 characters! Otherwise, an error message is
displayed.
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 18
3.1 Prerequisites
• An Eclipse target platform is added in the Run Configuration
• In the target platform, at least one ABAP project is added.
• Table Sflight should be filled with the corresponding entries. This table can be filled with entries by
running the report SAPBC_DATA_GENERATOR.
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 19
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 20
3.3.1 Implementing the Handler Method
1. Implement the SampleHandler class as follows:
package [Link].##.[Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
/**
* The constructor.
*/
public SampleHandler() {
}
/**
* Handler method
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 21
*/
public Object execute(ExecutionEvent event) throws ExecutionException {
// Create resource factory
IRestResourceFactory restResourceFactory = AdtRestResourceFactory
.createRestResourceFactory();
// Get available projects in the workspace
IProject[] abapProjects = AdtProjectServiceFactory
.createProjectService().getAvailableAbapProjects();
// Use the first project in the workspace for the demo
// to keep the example simple
IAbapProject abapProject = (IAbapProject) abapProjects[0]
.getAdapter([Link]);
// Trigger logon dialog if necessary
[Link]().ensureLoggedOn(
[Link](),
[Link]().getProgressService());
// Create REST resource for given destination and URI
String destination = [Link]();
URI flightUri = [Link](SAMPLE_FLIGHT_RESOURCE_URI);
IRestResource flightResource = restResourceFactory
.createResourceWithStatelessSession(flightUri, destination);
try {
// Trigger GET request on resource data
IResponse response = [Link](null,
[Link]);
// confirm that flight exists
openDialogWindow("Flight exists! HTTP-status:
"+[Link]([Link]()), "Flight Confirmation");
} catch (ResourceNotFoundException e) {
displayError("No flight data found");
} catch (RuntimeException e) {
// Display any kind of other error
displayError([Link]());
}
return null;
}
/*
* Display the exception text
*/
private void displayError(String messageText) {
String dialogTitle = "Flight Exception";
openDialogWindow(messageText, dialogTitle);
}
/*
* Display a simple dialog box with a text and an OK button to confirm
*/
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 22
protected void openDialogWindow(String dialogText, String dialogTitle) {
String[] DIALOG_BUTTON_LABELS = new String[] { IDialogConstants.OK_LABEL };
MessageDialog dialog = new MessageDialog(getShell(), dialogTitle, null,
dialogText, [Link], DIALOG_BUTTON_LABELS, 0);
[Link]();
}
}
2. Use shortcut Shift Ctrl O to organize the imports.
3. Check the SFLIGHT table in the backend for existing flights and modify the constant
SAMPLE_FLIGHT_RESOURCE_URI so that it represents an existing flight.
Note
For this, authorizations are required. See more in SAP Note 1657744.
// (imports skipped)
public class FlightData {
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 23
private String planeType;
private String price;
private String currency;
private String seatsMax;
private String seatsOccupied;
public FlightData() {}
NOTE
You will receive compiler warnings for the unused private attributes. In the source code editor, use the shortcut
ALT SHIFT S to add the following methods automatically:
• Use Generate Getters and Setters…
• Use Override/Implement Methods to:
o Add a toString() method
o Add a hashCode() method
o Add an equals() method
// (imports skipped)
public class FlightDataContentHandler implements IContentHandler<FlightData> {
@Override
public FlightData deserialize(IMessageBody body,
Class<? extends FlightData> dataType) {
// TODO Auto-generated method stub
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 24
return null;
}
@Override
public IMessageBody serialize(FlightData dataObject, Charset charset) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getSupportedContentType() {
return AdtMediaType.APPLICATION_XML;
}
@Override
public Class<FlightData> getSupportedDataType() {
return [Link];
}
}
NOTE
This package already exists in the "productive" Plug-in. Because we add tests for the *.data-Plug-in, the tests
should be part of the same package.
2. Accept the defaults on the first page and press Next.
3. In the new package, create the class TestsUnitFlightDataContentHandler and add the following
source code:
package [Link].##.[Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 25
import [Link];
import [Link];
import [Link];
import [Link];
@Test
public void deserialize() throws Exception {
@Test
public void serialize() throws Exception {
FlightDataContentHandler contentHandler = new FlightDataContentHandler();
FlightData flightData = new FlightData(CARRIER_ID, CONNECTION_ID, FLIGHT_DATE,
PLANETYPE, PRICE, CURRENCY, SEATSMAX, SEATS_OCCUPIED);
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 26
String expectedXML =
streamToString([Link]()).replaceAll("[\n\r ]", "");
if (stream == null) {
fail("No such file: '" + name + "' in " +
getClass().getProtectionDomain().getCodeSource().getLocation());
return null; // never happens
}
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 27
}
} finally {
try {
[Link]();
} catch (IOException e) { //$JL-EXC$ //NOPMD
}
}
return [Link]();
}
private static void resetStream(InputStream inputStream) {
try {
[Link]();
} catch (IOException e) { //$JL-EXC$ //NOPMD
// reset() yields IOException in some InputStream implementations
// cannot check this in advance
}
}
NOTE
So that you can avoid warnings due to discouraged access, the annotation @SuppressWarnings("restriction") is
added because this is not productive code.
...
private static final String FLIGHTS_ELEMENT = "flights";
private static final String ATTR_SEATSOCCUPIED = "seatsoccupied";
private static final String ATTR_SEATSMAX = "seatsmax";
private static final String ATTR_PLANETYPE = "planetype";
private static final String ATTR_CURRENCY = "currency";
private static final String ATTR_PRICE = "price";
private static final String ATTR_DATE = "date";
private static final String ATTR_CONNECTIONID = "connectionid";
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 28
private static final String ATTR_CARRIER_ID = "carrierid";
private static final String FLIGHT_ELEMENT = "flight";
private static final String HTTP_NAMESPACE =
"[Link]
protected final AdtStaxContentHandlerUtility utility = new
AdtStaxContentHandlerUtility();
@Override
public FlightData deserialize(IMessageBody body, Class<? extends FlightData>
dataType) {
XMLStreamReader xsr = null;
try {
xsr = [Link](body);
}
break;
}
}
return flightData;
} catch (XMLStreamException e) {
throw new ContentHandlerException([Link](), e);
} catch (NumberFormatException e) {
throw new ContentHandlerException([Link](), e);
} finally {
if (xsr != null) {
[Link](xsr);
}
}
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 29
}
@Override
public IMessageBody serialize(FlightData dataObject, Charset charset) {
try {
xsw = [Link](charset,
AdtStaxContentHandlerUtility.XML_VERSION_1_0);
[Link](FLIGHTS_ELEMENT, HTTP_NAMESPACE);
[Link](HTTP_NAMESPACE, FLIGHT_ELEMENT);
[Link](FLIGHTS_ELEMENT, HTTP_NAMESPACE);
[Link](ATTR_CARRIER_ID, [Link]());
[Link](ATTR_CONNECTIONID, [Link]());
[Link](ATTR_DATE, [Link]());
[Link](ATTR_PRICE, [Link]());
[Link](ATTR_CURRENCY, [Link]());
[Link](ATTR_PLANETYPE, [Link]());
[Link](ATTR_SEATSMAX, [Link]());
[Link](ATTR_SEATSOCCUPIED, [Link]());
[Link]();
[Link]();
} catch (XMLStreamException e) {
throw new ContentHandlerException(null, e);
} finally {
[Link](xsw);
}
return [Link]([Link]());
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 30
*
*/
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
/**
* Common constant for illegal (empty) argument exception messages.
*/
public static final String NO_CONTENT = "no content"; //$NON-NLS-1$
/**
* Common constant for default character set: UTF-8, platform-neutral.
*/
/**
* Checks if <tt>dataObject</tt> is not <tt>null</tt>.
*
* @param dataObject
* object to be checked.
* @throws IllegalArgumentException
* if object is <tt>null</tt>.
*/
public void serializeCheck(Object dataObject) {
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 31
if (dataObject == null) {
throw new IllegalArgumentException();
}
}
/**
* Returns the {@link #DEFAULT_CHARSET} if <tt>charset</tt> is <tt>null</tt>
* .
*
* @param charset
* character set to be checked.
* @return {@link #DEFAULT_CHARSET} if <tt>charset</tt> is <tt>null</tt> or
* <tt>charset</tt> otherwise.
*/
public Charset checkCharsetNotNull(Charset charset) {
if (charset == null) {
charset = DEFAULT_CHARSET;
}
return charset;
}
/**
* Creates a new XMLStreamWriter and starts an empty XML document.
*
* @param charset
* character set to be used or {@link #DEFAULT_CHARSET} if
* <tt>charset</tt> is <tt>null</tt>.
* @param version
* XML version to be used for the document. See
* {@link #XML_VERSION_1_0}.
* @returna new XMLStreamWriter with started document.
* @throws XMLStreamException
* internal StAX exception.
* @see {@link #getXMLStreamWriter(OutputStream, Charset)}
*/
public XMLStreamWriter getXMLStreamWriterAndStartDocument(Charset charset, String
version) throws XMLStreamException {
[Link] = new ByteArrayOutputStream();
charset = [Link](charset);
[Link]([Link](), version);
return xsw;
}
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 32
/**
* Creates a new XMLStreamWriter for a given stream.
*
* @param stream
* output stream to be used.
* @param charset
* character set to be used.
* @return new empty XMLStreamWriter.
* @throws XMLStreamException
* internal StAX exception.
*/
public XMLStreamWriter getXMLStreamWriter(OutputStream stream, Charset charset)
throws XMLStreamException {
final XMLOutputFactory xof = [Link]();
return xsw;
}
/**
* Creates a XMLStreamReader for a given message body.
*
* @param body
* message body to be opened for reading.
* @return new XMLStreamReader for <tt>body</tt>.
* @throws XMLStreamException
* internal StAX exception.
*/
try {
final InputStream is = [Link]();
return [Link](is);
} catch (IOException e) {
throw new ContentHandlerException([Link](), e);
}
}
/**
* Creates a XMLStreamReader for a given input stream
*
* @param stream
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 33
* stream to be used for reading
* @return new XMLStreamReader for <tt>stream</tt>.
* @throws XMLStreamException
* internal StAX exception
*/
public XMLStreamReader getXMLStreamReader(InputStream stream) throws
XMLStreamException {
if (stream == null) {
throw new IllegalArgumentException(NO_CONTENT);
}
final XMLInputFactory xif = [Link]();
return [Link](stream);
}
/**
* Creates a XMLStreamReader for a given message body.
*
* @param content
* the string to read
* @return new XMLStreamReader for <tt>content</tt>.
* @throws XMLStreamException
* internal StAX exception.
*/
public XMLStreamReader getXMLStreamReader(String content) throws XMLStreamException
{
if (content == null || [Link]() == 0) {
throw new IllegalArgumentException(NO_CONTENT);
}
/**
* Gracefully closes a given XMLStreamWriter.
*
* @param xsw
* a XMLStreamWriter.
*/
public void closeXMLStreamWriter(XMLStreamWriter xsw) {
if (xsw != null) {
try {
[Link]();
} catch (XMLStreamException e) { //$JL-EXC$ //NOPMD
}
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 34
}
try {
[Link]();
} catch (IOException e) { //$JL-EXC$ //NOPMD
}
}
/**
* Gracefully closes a given XMLStreamReader.
*
* @param xsr
* a XMLStreamReader.
*/
public void closeXMLStreamReader(XMLStreamReader xsr) {
if (xsr != null) {
try {
[Link]();
} catch (XMLStreamException e) { //$JL-EXC$ //NOPMD
}
}
}
/**
* Creates a message body from the current state of this
* AdtStaxContentHandlerUtility instance.
*
* @param supportedContentType
* content MIME type of the message body.
* @return newly created message body.
*/
public IMessageBody createMessageBody(String supportedContentType) {
byte[] data = [Link]();
return new ByteArrayMessageBody(supportedContentType, data);
}
}
...
public class SampleHandler extends AbstractHandler {
...
public Object execute(ExecutionEvent event) throws ExecutionException {
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 35
// Create resource factory
IRestResourceFactory restResourceFactory = AdtRestResourceFactory
.createRestResourceFactory();
// Get available projects in the workspace
IProject[] abapProjects = AdtProjectServiceFactory
.createProjectService().getAvailableAbapProjects();
// Use the first project in the workspace for the demo
// to keep the example simple
IAbapProject abapProject = (IAbapProject) abapProjects[0]
.getAdapter([Link]);
// Trigger logon dialog if necessary
[Link]().ensureLoggedOn(
[Link](),
[Link]().getProgressService());
// Create REST resource for given destination and URI
String destination = [Link](); URI flightUri =
[Link](SAMPLE_FLIGHT_RESOURCE_URI);
IRestResource flightResource = restResourceFactory
.createResourceWithStatelessSession(flightUri, destination);
// Create and add the content handler:
FlightDataContentHandler flightHandler = new FlightDataContentHandler();
[Link](flightHandler);
try {
// Trigger GET request on resource data
FlightData flightDataRead = [Link](null,
[Link]);
// Display some flight data in a popup window
displayFlight(flightDataRead);
} catch (ResourceNotFoundException e) {
displayError("No flight data found");
} catch (RuntimeException e) {
// Display any kind of other error
displayError([Link]());
}
return null;
}
/*
* Display the flight data which was read from the backend
*/
private void displayFlight(FlightData flightDataRead) {
String messageText = "Flight data found: "
+ [Link]() + " "
+ [Link]() + " Seats booked: "
+ [Link]() + "/"
+ [Link]();
openDialogWindow(messageText, "Flight Lookup");
}
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 36
}
NOTE
You can see that we have registered the content handler using the addContentHandler method of the resource.
The GET request is now able to return an instance of FlightData instead of the IRestResponse. The code
should compile.
/*
* Use Discovery Service to get the flight URI
*/
private URI getFlightURI(String destination, String carrierId, String connectionId,
String flightDate)
{
IAdtDiscovery discovery = [Link](destination,
[Link](MYCOMPANY_DISCOVERY)); // Get collection member by use of scheme and term
IAdtDiscoveryCollectionMember collectionMember =
[Link](SCHEME, TERM, new NullProgressMonitor());
IAdtTemplateLink templateLink =
[Link](FLIGHT_RELATION);
IAdtUriTemplate uriTemplate = [Link]();
String uri = [Link](URI_PARAMETER_CARRIER_ID,
carrierId).set(URI_PARAMETER_CONNECTION_ID,
connectionId).set(URI_PARAMETER_FLIGHT_DATE, flightDate).expand();
return [Link](uri);
}
3. Replace the existing assignment of the flight URI by a method call.
4. Run the SampleHandler on the target platform.
NOTE
The discovery service does not only provide a static collection URI for flights but also a template link that can be
instantiated by the client using parameters. You can see that it is easy to get and instantiate the link simply by
replacing the values of the URI parameters by the corresponding values.
How To... Create RESTful APIs and consume them in the ABAP Development Tools
Tutorial for Consuming REST Resources in the Eclipse Client © 2020 SAP AG or an SAP affiliate company. All rights reserved. 37
[Link]/contactsap
[Link]/irj/sdn/howtoguides