how to... build odata services using sap gateway
DESCRIPTION
SAP OData serviceTRANSCRIPT
SAP How-to Guide Mobility SAP Mobile Platform
Applicable Releases:
SAP Mobile Platform 3.0
SAP Gateway 2.0, SP07
Version 1.0
June 2015
How To... Build OData Services Using SAP Gateway
© Copyright 2015 SAP AG. All rights reserved.
No part of this publication may be reproduced or transmitted in any form or for
any purpose without the express permission of SAP AG. The information
contained herein may be changed without prior notice.
Some software products marketed by SAP AG and its distributors contain
proprietary software components of other software vendors.
Microsoft, Windows, Excel, Outlook, and PowerPoint are registered trademarks of
Microsoft Corporation.
IBM, DB2, DB2 Universal Database, System i, System i5, System p, System p5,
System x, System z, System z10, System z9, z10, z9, iSeries, pSeries, xSeries,
zSeries, eServer, z/VM, z/OS, i5/OS, S/390, OS/390, OS/400, AS/400, S/390 Parallel
Enterprise Server, PowerVM, Power Architecture, POWER6+, POWER6, POWER5+,
POWER5, POWER, OpenPower, PowerPC, BatchPipes, BladeCenter, System
Storage, GPFS, HACMP, RETAIN, DB2 Connect, RACF, Redbooks, OS/2, Parallel
Sysplex, MVS/ESA, AIX, Intelligent Miner, WebSphere, Netfinity, Tivoli and
Informix are trademarks or registered trademarks of IBM Corporation.
Linux is the registered trademark of Linus Torvalds in the U.S. and other countries.
Adobe, the Adobe logo, Acrobat, PostScript, and Reader are either trademarks or
registered trademarks of Adobe Systems Incorporated in the United States and/or
other countries.
Oracle is a registered trademark of Oracle Corporation.
UNIX, X/Open, OSF/1, and Motif are registered trademarks of the Open Group.
Citrix, ICA, Program Neighborhood, MetaFrame, WinFrame, VideoFrame, and
MultiWin are trademarks or registered trademarks of Citrix Systems, Inc.
HTML, XML, XHTML and W3C are trademarks or registered trademarks of W3C®,
World Wide Web Consortium, Massachusetts Institute of Technology.
Java is a registered trademark of Sun Microsystems, Inc.
JavaScript is a registered trademark of Sun Microsystems, Inc., used under license
for technology invented and implemented by Netscape.
SAP, R/3, SAP NetWeaver, Duet, PartnerEdge, ByDesign, SAP BusinessObjects
Explorer, StreamWork, and other SAP products and services mentioned herein as
well as their respective logos are trademarks or registered trademarks of SAP AG
in Germany and other countries.
Business Objects and the Business Objects logo, BusinessObjects, Crystal Reports,
Crystal Decisions, Web Intelligence, Xcelsius, and other Business Objects products
and services mentioned herein as well as their respective logos are trademarks or
registered trademarks of Business Objects Software Ltd. Business Objects is an
SAP company.
Sybase and Adaptive Server, iAnywhere, Sybase 365, SQL Anywhere, and other
Sybase products and services mentioned herein as well as their respective logos
are trademarks or registered trademarks of Sybase, Inc. Sybase is an SAP
company.
All other product and service names mentioned are the trademarks of their
respective companies. Data contained in this document serves informational
purposes only. National product specifications may vary.
The information in this document is proprietary to SAP. No part of this document
may be reproduced, copied, or transmitted in any form or for any purpose without
the express prior written permission of SAP AG.
This document is a preliminary version and not subject to your license agreement
or any other agreement with SAP. This document contains only intended
strategies, developments, and functionalities of the SAP® product and is not
intended to be binding upon SAP to any particular course of business, product
strategy, and/or development. Please note that this document is subject to change
and may be changed by SAP at any time without notice.
SAP assumes no responsibility for errors or omissions in this document. SAP does
not warrant the accuracy or completeness of the information, text, graphics, links,
or other items contained within this material. This document is provided without a
warranty of any kind, either express or implied, including but not limited to the
implied warranties of merchantability, fitness for a particular purpose, or non-‐
infringement.
SAP shall have no liability for damages of any kind including without limitation
direct, special, indirect, or consequential damages that may result from the use of
these materials. This limitation shall not apply in cases of intent or gross
negligence.
The statutory liability for personal injury and defective products is not affected.
SAP has no control over the information that you may access through the use of
hot links contained in these materials and does not endorse your use of third-‐
party Web pages nor provide any warranty whatsoever relating to third-‐party Web
pages.
SAP “How-‐to” Guides are intended to simplify the product implementtation. While
specific product features and procedures typically are explained in a practical
business context, it is not implied that those features and procedures are the only
approach in solving a specific business problem using SAP NetWeaver. Should you
wish to receive additional information, clarification or support, please refer to SAP
Consulting.
Any software coding and/or code lines / strings (“Code”) included in this
documentation are only examples and are not intended to be used in a productive
system environment. The Code is only intended better explain and visualize the
syntax and phrasing rules of certain coding. SAP does not warrant the correctness
and completeness of the Code given herein, and SAP shall not be liable for errors
or damages caused by the usage of the Code, except if such damages were caused
by SAP intentionally or grossly negligent.
Disclaimer
Some components of this product are based on Java™. Any code change in these
components may cause unpredictable and severe malfunctions and is therefore
expressively prohibited, as is any decompilation of these components.
Any Java™ Source Code delivered with this product is only to be used by SAP’s
Support Services and may not be modified or altered in any way.
Typographic Conventions
Type Style Description
Example Text Words or characters quoted from the screen. These include field names, screen titles, pushbuttons labels, menu names, menu paths, and menu options. Cross-‐references to other documentation
Example text Emphasized words or phrases in body text, graphic titles, and table titles
Example text File and directory names and their paths, messages, names of variables and parameters, source text, and names of installation, upgrade and database tools.
Example text User entry texts. These are words or characters that you enter in the system exactly as they appear in the documentation.
<Example text>
Variable user entry. Angle brackets indicate that you replace these words and characters with appropriate entries to make entries in the system.
EXAMPLE TEXT Keys on the keyboard, for example, F2 or ENTER.
Icons Icon Description
Caution
Note or Important
Example
Recommendation or Tip
Table of Contents
1. Business Scenario .................................................................................................. 1
2. Background Information ........................................................................................ 1
3. Prerequisites ......................................................................................................... 1
4. Step-‐by-‐Step Procedure ......................................................................................... 2 4.1 Option 1 -‐ Creating a Data Model by Importing the OData Model data .......... 2 4.2 Option 2 -‐ Creating a Data Model by Importing DDIC Structures .................... 7 4.3 Implementing Collection GET ......................................................................... 15 4.4 Implementing Filters ...................................................................................... 26 4.5 Implement Entity Create, Update, and Delete ............................................... 30
4.5.1 Implementing Entity Create ............................................................... 31 4.5.2 Implementing Entity Update .............................................................. 36 4.5.3 Implementing Entity Delete ............................................................... 38
4.6 Implementing Delta Token Support ............................................................... 40
How To... Build OData Services Using SAP Gateway
June 2015 1
1. Business Scenario The focus of this guide is on the SAP backend or server side process and the completion of the SAP backend implementation to prepare the OData service for exposure to the outside world.
2. Background Information For those who are new to the OData services development with SAP Gateway, here’s another H2G: OData CRUD Crash Course -‐ Getting ready with offline store The difference of this document is:
-‐ The data source is obtained via RFC -‐ It covers $expand, deep insert, and $filter
So this H2G is intended to provide you another implementation example.
3. Prerequisites In order to execute the tasks described in this How-‐To Guide, the following prerequisites must be met. • SAP NetWeaver Gateway 2.0, SP07 • ABAP development knowledge is recommended
Helpful Information • Note 1921547 -‐ How to integrate OData service with standard exchange table
How To... Build OData Services Using SAP Gateway
June 2015 2
4. Step-by-Step Procedure This section provides the detailed step-‐by-‐step procedure for designing and developing an end-‐to-‐end OData service. NOTE: In the next step, you can choose one of the listed methods below to create the data model:
• Option 1 -‐ Using an external model file • Option 2 -‐ Importing a ABAP DDIC structure or RFC/BOR interface In order to remain compatible with the code implementation sections that come later in this specific guide, it is recommended to use the “Import DDIC Structure” option for creating the data model. This is simply due to naming differences in the generated objects that results in using the different data model creation methods.
4.1 Option 1 - Creating a Data Model by Importing the OData Model data
For Data model design and creation of OData services, a number of tools exist to create the OData data model. Modeling can begin in an external client tool such as Microsoft Visual Studio and the OData Modeler tool. The latter is free and provided by SAP as a plugin for eclipse. An OData modeler is one of the components provided in the SMP tool. Once the models are created using such external tools, the model representation can be exported as an EDMX or XML formatted file. EDMX is an Entity Framework modeling XML format representing an Entity Data Model. SAP Gateway Service Builder can take these files as input and completely generate a model implementation as well as the shells for corresponding runtime implementations. SAP Gateway Service Builder is basically a design-‐time environment within the ABAP-‐based SAP Gateway system. It equips developers with a project-‐based service design and development tool and supports developers throughout the entire development lifecycle of an OData service.
How To... Build OData Services Using SAP Gateway
June 2015 3
A similar data model can be created using the OData modeling tool which can then be used as a basis to generate the ABAP runtime artifacts on the Gateway system.
Figure : OData Modeler
But note that using an external model file is just one of the options to use as a basis for creating the data model using Service Builder. Other options such as leveraging inherent ABAP data dictionary structures, BOR objects, and RFC interfaces are available as well.
Create a New Project Using Service Builder 1. Log into your SAP NetWeaver Gateway system and proceed to transaction SEGW. 2. Click on the Create Project button on the main toolbar.
How To... Build OData Services Using SAP Gateway
June 2015 4
3. On the subsequent Create Project dialog, enter a package you want to use for the
project. If you don’t have one in mind, simply select the Local Object button.
Create the Data Model Using an External Model File Entity Data Models can be created using external tools such as Microsoft Visual Studio and recently, the OData Modeler tool. The SMP tool has an OData Modeler component that helps you create data models for OData services. More information can be found on the SAP HANA Cloud Documentation site. 1. Prepare your XML file – (you can use the $metadata file of your OData service too) 2. In your created project, right-‐click on Data Model and select Import à Data Model
from File from the context menu.
How To... Build OData Services Using SAP Gateway
June 2015 5
3. Browse to the location of the XML model file and select Next.
4. The next screen of the File Import wizard shows an outline of the model contents. You can see the Entity Types as well as the relationships defined within the model.
5. Click on Finish.
How To... Build OData Services Using SAP Gateway
June 2015 6
Your project data model should now reflect what was described in the model metadata file. Save your project.
How To... Build OData Services Using SAP Gateway
June 2015 7
4.2 Option 2 - Creating a Data Model by Importing DDIC Structures
You can leverage existing ABAP data dictionary (DDIC) structures, BOR objects, and RFC interfaces to help you create data model objects such as entity types. In this guide, we will use DDIC structures. 1. In your created project, right-‐click on Data Model and select Import à DDIC Structure
from the context menu.
2. For the ABAP Structure, enter BAPI_EPM_BP_HEADER and press <Enter>.
As a result, you will see a list fields/properties contained with the structure. 3. For Object Name, overwrite the defaulted value (e.g. “BapiEpmBpHeader”) and replace
it with BusinessPartner. 4. Make field/property BP_ID a Key field by selecting Key in the corresponding Usage
column drop-‐down.
How To... Build OData Services Using SAP Gateway
June 2015 8
5. Click the Continue button on the lower right to finish the DDIC import. As a result, you should see the BusinessPartner Entity Type created within the Data Model of your project.
6. Repeat steps 1 through 5 to import DDIC structures for the SalesOrder and
SalesOrderItem entities: SalesOrder: -‐ ABAP Structure: BAPI_EPM_SO_HEADER -‐ Object Name: SalesOrder -‐ Key field: SO_ID
SalesOrder: -‐ ABAP Structure: BAPI_EPM_SO_ITEM -‐ Object Name: SalesOrderItem -‐ Key field: SO_ID, SO_ITEM_POS
7. Save your project.
How To... Build OData Services Using SAP Gateway
June 2015 9
Now we have corresponding Entity Sets. Entity Sets will represent Collections of entities in the OData service. NOTE: The screen captures in this doc were taken in the older SAP Gateway. In your newer SP version of Gateway should generate entity sets that has the naming convention with “…Set”.
8. Now create Associations by double-‐clicking on the Associations node on the left pane. On the right pane, click on the Append Row button (twic) and enter Associations called BusinessPartner_SalesOrder and SalesOrder_SalesOrderItem.
9. Enter the Principal and Dependent Entity and corresponding Cardinalities as shown below.
Each association reflects a one-‐to-‐many (1 to M) relationship between the principal and dependent entities. So, put simply, a Business Partner can have many Sales Orders and a Sales Order can have many Sales Order Items. As you might have noticed, Associations defines the relationships between entities.
10. Now create a Referential Constraint for the SalesOrder_SalesOrderItem association. A Referential Constraint is similar to the concept of foreign keys in relational tables. Double-‐click on the Referential Constraint node under the SalesOrder_SalesOrderItem association.
11. On the right pane, click on Append Row and simply select the SoID value for the Principal Key and also for the Dependent Property, then press <Enter>. The other fields will populate automatically.
12. Based on the relationships defined in the Associations, we can build Navigation
Properties for specific entity types. For example, since a BusinessPartner can have many Sales Orders, we want to build a Navigation Property that can be used to “navigate” from a BusinessPartner instance to its associated SalesOrder collection.
How To... Build OData Services Using SAP Gateway
June 2015 10
13. Double-‐click on Navigation Properties under the BusinessPartner Entity Type. Click on Append Row and enter SalesOrders for the Name and select BusinessPartner_SalesOrder for Relationship Name.
14. Double-‐click on Navigation Properties under the SalesOrder Entity Type and append
two new rows. Name the Navigations BusinessPartner and Items with Relationship Names BusinessPartner_SalesOrder and SalesOrder_SalesOrderItem respectively.
15. Save your project. 16. Finally create Association Sets. An association set is simply a logical container for
association instances of the same type. 17. Create an association set by right-‐clicking on Data Model and selecting Create à
Association Set from the context menu.
Enter BusinessPartner_SalesOrder_AssocSet as the Name and select BusinessPartner_SalesOrder as the association.
How To... Build OData Services Using SAP Gateway
June 2015 11
18. Append a new row and add an association set called SalesOrder_SalesOrderItem_AssocSet with SalesOrder_SalesOrderItem as the association and press <Enter>.
The resulting association sets should appear as below.
19. Save your project. 20. Generate the runtime objects by selecting the Generate button on the main toolbar.
You can leave in the default values and press Continue/Enter . Note that the Technical Service Name field within the Service Registration section reflects the name of the service exposed in the Service URL.
How To... Build OData Services Using SAP Gateway
June 2015 12
Select Local Object unless you have a specific Package you want to use for these objects.
As a result, based on the Data Model created, a number of runtime ABAP objects were generated in the background. Corresponding model class implementations along with data provider shells were generated to prepare the OData service to be exposed to the outside world.
Service Maintenance and Initial Test We have used the Service Builder to help us create an OData model and generate the runtime ABAP components. Now we need to expose the service on Gateway and conduct an initial test. The Service Maintenance function in the Service Builder enables you to register and maintain each service in an SAP Gateway system. Prerequisites The SAP Gateway systems in which you want to register the service must be configured under the following path: SPRO à SAP NetWeaver à Gateway Service Enablement à Backend OData Channel à Connection Settings to SAP NetWeaver Gateway à SAP NetWeaver Gateway Settings. 1. In Service Builder, double-‐click on the Service Maintenance folder within your project
to view the configured systems. 2. Select the system you want to register the service in and click on the Register Service
button. If you do not have any system listed, see the prerequisites above.
Select Yes in the warning dialog.
How To... Build OData Services Using SAP Gateway
June 2015 13
As a result, the registration status next for the system you registered the service should be green.
3. Now let’s do an initial service call to test the service. Select the Maintain button.
4. In the lower left section, launch the Gateway Client by selecting the Gateway Client
button.
The Gateway Client should open in another window.
5. The Request URI value represents the OData Service Document URL of this service. 6. Select the Execute (F8) button.
7. As a result, the response section on the right should show an HTTP response code of
200…
How To... Build OData Services Using SAP Gateway
June 2015 14
…and you should see the Service Document showing the Collections (BusinessPartners, SalesOrders, and SalesOrderItems) available for this service.
8. To view the metadata of the service, overwrite the “?$format=xml” at the end of the
URL with $metadata.
9. As a result, the metadata for the service is displayed. If you examine it closely, you
should see that it directly corresponds to the data model you created in the previous steps.
Back out to exit the GW Client for now and then back again to return to main Service Builder screen.
How To... Build OData Services Using SAP Gateway
June 2015 15
4.3 Implementing Collection GET Each Entity (e.g. BusinessPartner) has a corresponding Service Implementation that is executed at runtime. Standard operations such as Create, Read, Update, and Delete (CRUD) as well as Query can be implemented to support the maintenance of the entity. As mentioned earlier, after a project and its data model are generated, the runtime implementation shells are generated as well. In order for the corresponding service operations to be useful, they must be implemented in ABAP to return or process business data. A standard set of five method shells will be generated for each entity type:
• <Entity>_GET_ENTITYSET • <Entity>_GET_ENTITY • <Entity>_CREATE_ENTITY • <Entity>_UPDATE_ENTITY • <Entity>_DELETE_ENTITY
Depending on the Entity, operation type, and the corresponding business object in the business backend, the actual implementation can vary from quite simple to complex. Although we do not cover it in this guide, note that other OData operations such as Function Import can be implemented as well. We begin with the implementation of GET_ENTITYSET which corresponds to a common “Get List” query and is also functionally equivalent to a full MBO download. Without any filters, a standard GET_ENTITYSET operation call returns the entire entity collection. The GET_ENTITYSET method will be implemented for all three of our entity sets: BusinessPartnerSet, SalesOrderSet, and SalesOrderItemSet.
Implement Method BUSINESSPARTNERS_GET_ENTITYSET 1. In Service Builder, expand the Service Implementation and then the BusinessPartnerSet
node. Right-‐click on GetEntitySet (Query) and select Go to ABAP Workbench from the context menu.
How To... Build OData Services Using SAP Gateway
June 2015 16
An information dialog will display. Select the Continue button to proceed with the implementation.
2. Once in the Class Builder, 1) toggle into edit mode, 2) scroll down and place the cursor
in the BUSINESSPARTNERS_GET_ENTITYSET method row, and 3) select the Redefine button.
This opens up the BUSINESSPARTNERS_GET_ENTITYSET implementation.
3. From the Edit menu, select Pattern.
4. Enter function name BAPI_EPM_BP_GET_LIST and press <Enter>.
How To... Build OData Services Using SAP Gateway
June 2015 17
5. Uncomment the line with TABLES and BPHEADERDATA by deleting the asterisk (*) and
add et_entityset as the table variable to correspond to BPHEADERDATA.
If desired, you can cut and paste from below instead.
method BUSINESSPARTNERS_GET_ENTITYSET. CALL FUNCTION 'BAPI_EPM_BP_GET_LIST' * EXPORTING * MAX_ROWS = TABLES * SELPARAMBPID = * SELPARAMCOMPANYNAME = BPHEADERDATA = et_entityset * BPCONTACTDATA = * RETURN = . endmethod.
As you can see, the implementation is simple. The BAPI_EPM_BP_GET_LIST function is called to get the list of business partners and the result is captured and passed out through et_entityset.
6. Select the Activate button.
How To... Build OData Services Using SAP Gateway
June 2015 18
Confirm that the three objects are selected for activation as shown below and continue .
If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
7. Go back to the Class Interface screen.
Implement Method SALESORDERS_GET_ENTITYSET 1. Scroll down to the SALESORDERS_GET_ENTITYSET method, place the cursor in the row,
and select the Redefine button. 2. Implement the method with the following code.
method SALESORDERS_GET_ENTITYSET. field-symbols: <fs_key> type /iwbep/s_mgw_name_value_pair. data: ls_company_name type SNWD_COMPANY_NAME. data: lt_range type table of BAPI_EPM_CUSTOMER_NAME_RANGE, ls_range type BAPI_EPM_CUSTOMER_NAME_RANGE, lv_bp_id(10) type N. * Return all SalesOrders if no navigation path. if it_navigation_path is initial. CALL FUNCTION 'BAPI_EPM_SO_GET_LIST' * EXPORTING * MAX_ROWS = TABLES SOHEADERDATA = et_entityset * SOITEMDATA = * SELPARAMSOID = * SELPARAMBUYERNAME = * SELPARAMPRODUCTID = * RETURN = .
How To... Build OData Services Using SAP Gateway
June 2015 19
else. * Navigation path from BusinessPartners. Return sales orders for a specific business partner. * However, can only lookup using "Company Name", not BP_ID. So need to get Company Name using BP_ID first. read table it_key_tab assigning <fs_key> index 1. lv_bp_id = <fs_key>-value. * Look up buyer name based on BP_ID select single company_name from snwd_bpa into ls_company_name where bp_id = lv_bp_id. ls_range-sign = 'I'. ls_range-option = 'EQ'. ls_range-low = ls_company_name. append ls_range to lt_range. CALL FUNCTION 'BAPI_EPM_SO_GET_LIST' * EXPORTING * MAX_ROWS = TABLES SOHEADERDATA = et_entityset * SOITEMDATA = * SELPARAMSOID = SELPARAMBUYERNAME = lt_range * SELPARAMPRODUCTID = * RETURN = . endif. endmethod.
For Sales Orders, the resulting list of sales order entities depends primarily on whether a navigation path (e.g. from BusinessPartnerSet) is being followed or not. If so, we need to read the key of the BusinessPartner instance passed in and look up Sales Orders that belong to that Business Partner. One twist is that the function we want to use to return the sales order list, BAPI_EPM_SO_GET_LIST, has a selection parameter for the buyer name (or company name), not the BP_ID. This opens up the possibility that a duplicate company name will return sales orders of a different buyer. However, for simplicity, we will stick with this. If a navigation path does not exist, then all the sales orders entities are returned.
3. Activate the implementation. If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
4. Go back to the Class Interface screen.
How To... Build OData Services Using SAP Gateway
June 2015 20
Implement Method SALESORDERITEMS_GET_ENTITYSET
5. Scroll down to the SALESORDERITEMS_GET_ENTITYSET method, place the cursor in the row, and select the Redefine button.
6. Implement the method with the following code.
method SALESORDERITEMS_GET_ENTITYSET. data: lt_range type table of BAPI_EPM_SO_ID_RANGE, ls_range type BAPI_EPM_SO_ID_RANGE, lv_so_id(10) type N. field-symbols: <fs_key> type /iwbep/s_mgw_name_value_pair. * We want to limit access to SalesOrderItmes only through a navigation path or $expand option. if it_navigation_path is initial. * If it's not, raise an exception. RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception EXPORTING textid = /iwbep/cx_mgw_busi_exception=>business_error_unlimited message_unlimited = 'SalesOrderItems can only be accessed from a Sales Order navigation path or using the $expand=Items option.'. else. * There is a navigation path. Read only items for a particular SO * SO ID should be in it_key_tab. read table it_key_tab assigning <fs_key> index 1. lv_so_id = <fs_key>-value. ls_range-sign = 'I'. ls_range-option = 'EQ'. ls_range-low = lv_so_id. append ls_range to lt_range. CALL FUNCTION 'BAPI_EPM_SO_GET_LIST' * EXPORTING * MAX_ROWS = TABLES * SOHEADERDATA = SOITEMDATA = et_entityset SELPARAMSOID = lt_range * SELPARAMBUYERNAME = * SELPARAMPRODUCTID = * RETURN = . endif.
How To... Build OData Services Using SAP Gateway
June 2015 21
endmethod.
For Sales Order Items, we only want to return items within the context of its parent Sales Order, so if a navigation path does not exist, an exception is raised. Otherwise, the SO_ID is read from the key table (it_key_tab) and used to get the list of sales order items that belong to the sales order.
7. Activate the implementation. If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
8. Go back to the Class Interface screen.
Test the GET_ENTITYSET Implementations 9. Navigate to the Gateway Client via Service Maintenance (i.e. double-‐click Service
Maintenance folder on left and select the Maintain button on the right). You can also open a separate Gateway Client window by entering /o/IWFND/GW_CLIENT transaction code. In this case, replace the default Request URI with the base service URI of our service (/sap/opu/odata/sap/Z_EPM_RKT_SRV/).
10. First test getting the BusinessPartnerSet entity set. 11. Append BusinessPartnerSet to the end of the Request URI and select Execute (F8).
12. As a result, you should get a list of BusinessPartner entries returned.
How To... Build OData Services Using SAP Gateway
June 2015 22
13. Now overwrite BusinessPartnerSet with SalesOrderSet in the Request URI and select
Execute (F8).
As a result, you should get a complete list of SalesOrder entries returned.
Implement GET_ENTITY for SalesOrder and BusinessPartner Remember that for sales order items, the only items returned are those in the context of a specific sales order. So we first have to complete the implementation of reading a specific sales order first. This is done in the GET_ENTITY method. Whereas a GET_ENTITYSET method corresponds to a QUERY operation that returns 0 to many entries, a GET_ENTITY method corresponds to a READ operation that returns 0 to at most 1 entry. While we’re at it, we’ll implement the GET_ENTITY method for the BusinessPartner entity as well. 1. Scroll down to the SALESORDER_GET_ENTITY method, place the cursor in the row, and
select the Redefine button. 2. Implement the method with the following code.
method SALESORDERS_GET_ENTITY. DATA: lt_keys TYPE /IWBEP/T_MGW_TECH_PAIRS, ls_key TYPE /IWBEP/S_MGW_TECH_PAIR,
How To... Build OData Services Using SAP Gateway
June 2015 23
ls_so_id type BAPI_EPM_SO_ID, lv_so_id(10) type N. lt_keys = IO_TECH_REQUEST_CONTEXT->GET_KEYS( ). READ TABLE lt_keys with key name = 'SO_ID' INTO ls_key. lv_so_id = ls_key-value. ls_so_id-so_id = lv_so_id. CALL FUNCTION 'BAPI_EPM_SO_GET_DETAIL' EXPORTING SO_ID = ls_so_id IMPORTING HEADERDATA = er_entity * TABLES * CONTACTDATA = * RETURN = lt_return . endmethod.
The BAPI function BAPI_EPM_SO_GET_DETAIL is used to return the sales order header information using the SO_ID key passed in.
3. Activate the implementation. If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
4. Go back to the Class Interface screen. 5. Scroll down to the BUSINESSPARTNER_GET_ENTITY method, place the cursor in the
row, and select the Redefine button. 6. Implement the method with the following code.
method BUSINESSPARTNERS_GET_ENTITY. DATA: lt_keys TYPE /IWBEP/T_MGW_TECH_PAIRS, ls_key TYPE /IWBEP/S_MGW_TECH_PAIR, ls_bp_id type BAPI_EPM_BP_ID, lv_bp_id(10) type N. lt_keys = IO_TECH_REQUEST_CONTEXT->GET_KEYS( ). READ TABLE lt_keys with key name = 'BP_ID' INTO ls_key. lv_bp_id = ls_key-value. ls_bp_id-bp_id = lv_bp_id. CALL FUNCTION 'BAPI_EPM_BP_GET_DETAIL' EXPORTING BP_ID = ls_bp_id IMPORTING HEADERDATA = er_entity * TABLES
How To... Build OData Services Using SAP Gateway
June 2015 24
* CONTACTDATA = * RETURN = lt_return . endmethod.
The BAPI function BAPI_EPM_BP_GET_DETAIL is used to return the business partner header information using the BP_ID key passed in.
7. Activate the implementation. If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
8. Go back to the Class Interface screen.
Test the GET_ENTITY Implementations and Navigation Functionality 1. Navigate to the Gateway Client via Service Maintenance (i.e. double-‐click Service
Maintenance folder on left and select the Maintain button on the right). You can also open a separate Gateway Client window by entering /o/IWFND/GW_CLIENT transaction code. In this case, replace the default Request URI with the base service URI of our service (/sap/opu/odata/sap/Z_EPM_RKT_SRV/). First test reading a single SalesOrder entry.
2. Again, append SalesOrderSet to the end of the Request URI and select Execute (F8). 3. In the result, go to an <entry> element and look for a href link specifying a specific
SalesOrder entry such as SalesOrderSet('500000000').
4. Append the href value (e.g. SalesOrderSet('500000000')) to the end of the URL and
select Execute (F8).
How To... Build OData Services Using SAP Gateway
June 2015 25
One entry should be returned showing the detailed properties of the specified sales order.
5. Now append Items to the current URI and execute (F8).
6. As a result, all the sales order items for the specified sales order are returned.
7. Now overwrite “/Items” with ?$expand=Items and execute (F8).
What is the difference between this query and the previous one? You may notice that this result also contains all the sales order items for a given sales order. But in addition, at the bottom, it also includes the sales order header information. System Query Option – $expand The $expand OData system query option (OData – $expand) makes it possible, for example, to Read a full sales order using one call – i.e., a sales order header along with all of its corresponding item entries in an inline, deep format. This is possible due to the associations and navigation properties set up in our data model. The one-‐to-‐many association between SalesOrder and SalesOrderItem along
How To... Build OData Services Using SAP Gateway
June 2015 26
with the navigation property, Items (allowing for navigation from SalesOrder to SalesOrderItemSet), is the basis for reading or creating our sales order header entries “deeply” with inline sales order item entries. The central runtime interface, /IWBEP/IF_MGW_APPL_SRV_RUNTIME, also provides the GET_EXPANDED_ENTITY and GET_EXPANDED_ENTITYSET methods for reading or querying entity data in a deep/inline format.
Note The SAP Gateway framework provides a default implementation of these methods, which can completely handle expand requests in a generic way. However, you do have the option to redefine the methods with your own implementation if necessary (e.g. in case of performance-‐critical scenarios or if you experience a bad response time).
8. To make sure the GET_ENTITY for the BusinessPartner is working, append BusinessPartnerSet to the end of the Request URI and select Execute (F8).
9. In the result set, find a valid business partner ID (e.g. BusinessPartnerSet('100000000')) and execute again. As a result, a single BusinessPartner entry along with its details should be returned.
4.4 Implementing Filters The OData $filter system query option provides the functionality to query for a subset of the Entries from the Collection of Entries using an expression specified in the query option. For example, the expression .../SalesOrderSet?$filter=SoID eq '500000000' would return the Sales Order with SoID equal to ‘500000000’. As another example, the expression …/SalesOrderSet?$filter=BuyerName eq 'SAP' would return Sales Orders bought from customer ‘SAP’. As such, the filtering capability, along with delta query functions (discussed in later chapters), can potentially be used to functionality meet the requirements set for MBOs and its use for load parameters, sync parameters, and personalization keys. However, due to the inherent differences between MBOs and the OData standard, a direct mapping between respective features cannot be achieved and limitations from either perspective are to be expected. In this context, we proceed below with details on how to implement filter handling in OData query operations (GET_ENTITYSET methods). 1. Go back to the Class Builder screen for class ZCL_Z_EPM_RKT_DPC_EXT and open the
implementation of the method BUSINESSPARTNERS_GET_ENTITYSET. Change to edit mode if necessary.
2. Re-‐implement the method with the following code. New code is highlighted in green.
method BUSINESSPARTNERS_GET_ENTITYSET. DATA:ls_filter_select_options TYPE /iwbep/s_mgw_select_option,
How To... Build OData Services Using SAP Gateway
June 2015 27
ls_mgw_select_options TYPE /iwbep/s_mgw_select_option, ls_mgw_range_options TYPE /iwbep/s_cod_select_option, ls_range_bpid TYPE BAPI_EPM_BP_ID_RANGE, lt_range_bpid TYPE TABLE OF BAPI_EPM_BP_ID_RANGE, ls_range_companyname TYPE BAPI_EPM_COMPANY_NAME_RANGE, lt_range_companyname TYPE TABLE OF BAPI_EPM_COMPANY_NAME_RANGE. DATA:lv_bpid_low(10) TYPE N, lv_bpid_high(10) TYPE N, ls_max_rows TYPE BAPI_EPM_MAX_ROWS. * Process filters LOOP AT it_filter_select_options INTO ls_filter_select_options. LOOP AT ls_filter_select_options-select_options INTO ls_mgw_range_options. TRANSLATE ls_filter_select_options-property TO UPPER CASE. CASE ls_filter_select_options-property. WHEN 'BPID'. lv_bpid_low = ls_mgw_range_options-low. "Workaround for adding leading zeros if ls_mgw_range_options-high is not initial. lv_bpid_high = ls_mgw_range_options-high. endif. MOVE-CORRESPONDING ls_mgw_range_options TO ls_range_bpid. ls_range_bpid-low = lv_bpid_low. if ls_range_bpid-high is not initial. ls_range_bpid-high = lv_bpid_high. endif. APPEND ls_range_bpid TO lt_range_bpid. WHEN 'COMPANYNAME'. MOVE-CORRESPONDING ls_mgw_range_options TO ls_range_companyname. APPEND ls_range_companyname TO lt_range_companyname. ENDCASE. ENDLOOP. ENDLOOP.
How To... Build OData Services Using SAP Gateway
June 2015 28
ls_max_rows-bapimaxrow = is_paging-top. CALL FUNCTION 'BAPI_EPM_BP_GET_LIST' EXPORTING MAX_ROWS = ls_max_rows TABLES SELPARAMBPID = lt_range_bpid SELPARAMCOMPANYNAME = lt_range_companyname BPHEADERDATA = et_entityset * BPCONTACTDATA = * RETURN = . endmethod.
We are mainly adding some code to account for filtering before the call to BAPI function BAPI_EPM_BP_GET_LIST is made.
3. Activate the implementation. If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
4. Go back to the Class Interface screen. 5. Open the implementation of the method SALESORDERS_GET_ENTITYSET and change
to edit mode if necessary. 6. Re-‐implement the method with the following code. New code is highlighted in green.
method SALESORDERS_GET_ENTITYSET. DATA:ls_filter_select_options TYPE /iwbep/s_mgw_select_option, ls_mgw_select_options TYPE /iwbep/s_mgw_select_option, ls_mgw_range_options TYPE /iwbep/s_cod_select_option, ls_range_soid TYPE BAPI_EPM_SO_ID_RANGE, lt_range_soid TYPE TABLE OF BAPI_EPM_SO_ID_RANGE, ls_range_buyername TYPE BAPI_EPM_CUSTOMER_NAME_RANGE, lt_range_buyername TYPE TABLE OF BAPI_EPM_CUSTOMER_NAME_RANGE. DATA:lv_soid_low(10) TYPE N, lv_soid_high(10) TYPE N, ls_max_rows TYPE BAPI_EPM_MAX_ROWS. field-symbols: <fs_key> type /iwbep/s_mgw_name_value_pair. data: ls_company_name type SNWD_COMPANY_NAME. data: lt_range type table of BAPI_EPM_CUSTOMER_N
How To... Build OData Services Using SAP Gateway
June 2015 29
AME_RANGE, ls_range type BAPI_EPM_CUSTOMER_NAME_RANGE, lv_bp_id(10) type N. * Return all SalesOrders if no navigation path. if it_navigation_path is initial. * Process filters LOOP AT it_filter_select_options INTO ls_filter_select_options. LOOP AT ls_filter_select_options-select_options INTO ls_mgw_range_options. TRANSLATE ls_filter_select_options-property TO UPPER CASE. CASE ls_filter_select_options-property. WHEN 'SOID'. lv_soid_low = ls_mgw_range_options-low. "Workaround for adding leading zeros if ls_mgw_range_options-high is not initial. lv_soid_high = ls_mgw_range_options-high. endif. MOVE-CORRESPONDING ls_mgw_range_options TO ls_range_soid. ls_range_soid-low = lv_soid_low. if ls_range_soid-high is not initial. ls_range_soid-high = lv_soid_high. endif. APPEND ls_range_soid TO lt_range_soid. WHEN 'BUYERNAME'. MOVE-CORRESPONDING ls_mgw_range_options TO ls_range_BUYERNAME. APPEND ls_range_BUYERNAME TO lt_range_BUYERNAME. ENDCASE. ENDLOOP. ENDLOOP. ls_max_rows-bapimaxrow = is_paging-top. CALL FUNCTION 'BAPI_EPM_SO_GET_LIST' EXPORTING MAX_ROWS = ls_max_rows TABLES SOHEADERDATA = et_entityset * SOITEMDATA = SELPARAMSOID = lt_range_soid
How To... Build OData Services Using SAP Gateway
June 2015 30
SELPARAMBUYERNAME = lt_range_buyername * SELPARAMPRODUCTID = * RETURN = . else. * Navigation path from BusinessPartners. Return sales orders for a specific business partner. * However, can only lookup using "Company Name", not BP_ID. So need to get Company Name using BP_ID first. read table it_key_tab assigning <fs_key> index 1. lv_bp_id = <fs_key>-value. * Look up buyer name based on BP_ID select single company_name from snwd_bpa into ls_company_name where bp_id = lv_bp_id. ls_range-sign = 'I'. ls_range-option = 'EQ'. ls_range-low = ls_company_name. append ls_range to lt_range. CALL FUNCTION 'BAPI_EPM_SO_GET_LIST' * EXPORTING * MAX_ROWS = TABLES SOHEADERDATA = et_entityset * SOITEMDATA = * SELPARAMSOID = SELPARAMBUYERNAME = lt_range * SELPARAMPRODUCTID = * RETURN = . endif. endmethod.
We are mainly adding some code to account for filtering before the call to BAPI function BAPI_EPM_BP_GET_LIST is made.
7. Activate the implementation. If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
8. Go back to the Class Interface screen.
4.5 Implement Entity Create, Update, and Delete
How To... Build OData Services Using SAP Gateway
June 2015 31
An OData service provides functionality by leveraging REST compliant, HTTP based requests using the POST, PUT, and DELETE methods to Create, Update, or Delete entities respectively. SAP Gateway exposes such OData services and provides an OData channel runtime API that can be used to implement the Create, Update, and Delete operations on the ABAP backend. The ABAP interface /IWBEP/IF_MGW_APPL_SRV_RUNTIME is the central implemented by every data provider class of a Gateway exposed OData service. It contains the all the relevant methods for Creating, Updating, and Deleting entities, as well as those used for retrieving or downloading data (e.g. GET_ENTITYSET) used in previous sections. For Create, Update, and Delete the relevant methods are:
• CREATE_ENTITY and CREATE_DEEP_ENTITY • UPDATE_ENTITY • DELETE_ENTITY
Details on how to implement these methods are provided in the following sections.
4.5.1 Implementing Entity Create Creating an implementation for the CREATE operation can be done in one of two ways.
1.) The first method uses the CREATE_ENTITY method where a single entry is created with one call.
2.) The second method uses the CREATE_DEEP_ENTITY method where a single entry along with related inline entries is created with one call. For example, a sales order along with its sales order line items is created together in one operation.
For our scenario, we will use CREATE_ENTITY for creating a BusinessPartner entity and CREATE_DEEP_ENTITY for creating a SalesOrder along with SalesOrderItemSet. 1. On the Class Builder screen for class ZCL_Z_EPM_RKT_DPC_EXT, scroll down to the
BUSINESSPARTNERS_CREATE_ENTITY method, place the cursor in the row, and select the Redefine button.
2. Implement the method with the following code.
method BUSINESSPARTNERS_CREATE_ENTITY. data: lv_id type snwd_partner_id, ls_id type bapi_epm_bp_id. data: ls_headerdata type bapi_epm_bp_header, lt_return type table of bapiret2, ls_return type bapiret2, err_msg type string, lo_message_container type ref to /iwbep/if_message_container. data: ls_message type scx_t100key, lt_keys type /iwbep/t_mgw_tech_pairs, ls_snwd_bpa type snwd_bpa.
How To... Build OData Services Using SAP Gateway
June 2015 32
DATA: lv_timestamp TYPE timestamp. field-symbols: <ls_key> type /iwbep/s_mgw_tech_pair. io_data_provider->read_entry_data( importing es_data = ls_headerdata ). call function 'BAPI_EPM_BP_CREATE' exporting headerdata = ls_headerdata " EPM: BP header data importing businesspartnerid = ls_id tables return = lt_return. " Return Parameter if lt_return is not initial. loop at lt_return into ls_return. err_msg = ls_return-message . endloop. ls_message-msgid = 'SY'. ls_message-msgno = '002'. ls_message-attr1 = err_msg. raise exception type /iwbep/cx_mgw_busi_exception exporting textid = ls_message. endif. CALL FUNCTION 'BAPI_EPM_BP_GET_DETAIL' EXPORTING BP_ID = ls_id IMPORTING HEADERDATA = er_entity * TABLES * CONTACTDATA = * RETURN = lt_return . endmethod.
The body of the request is passed in through the es_data structure and captured in ls_headerdata. The data is then used as input for the BAPI function BAPI_EPM_BP_CREATE. The OData standard specifies that for a POST/CREATE operation, the created entity data should be returned in the body of the response. This is why in the above implementation, a call to function BP_EPM_BP_GET_DETAIL is made, using the BP_ID resulting from the create call, to capture and return the BusinessPartner entry data in the er_entity structure, which is used to pass back the data in the response body.
How To... Build OData Services Using SAP Gateway
June 2015 33
3. Activate the implementation. If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
4. Go back to the Class Interface screen. 5. Scroll to the /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY method.
Note that in your view, the text color will still be in blue indicating it has yet to be redefined.
6. Place the cursor in the row, and select the Redefine button. 7. Implement the method with the following code.
method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY. types: ty_t_soitem type standard table of zcl_z_epm_rkt_mpc=>ts_salesorderitem with default key. * Represents full Sales Order structure - header with one or more items types: begin of ty_s_so. include type zcl_z_epm_rkt_mpc=>ts_salesorder. types: items type ty_t_soitem, end of ty_s_so. data: ls_so type ty_s_so, ls_item type zcl_z_epm_rkt_mpc=>ts_salesorderitem, lv_compare_result type /iwbep/if_mgw_odata_expand=>ty_e_compare_result.
How To... Build OData Services Using SAP Gateway
June 2015 34
data: lv_so_id type BAPI_EPM_SO_ID, ls_sohdr type BAPI_EPM_SO_HEADER, ls_sohdr2 type BAPI_EPM_SO_HEADER, ls_soitem type BAPI_EPM_SO_ITEM, lt_soitem type standard table of BAPI_EPM_SO_ITEM, lt_soitem2 type standard table of BAPI_EPM_SO_ITEM, lt_return type bapirettab, ls_return TYPE bapiret2, lx_busi_exc TYPE REF TO /iwbep/cx_mgw_busi_exception, lo_meco TYPE REF TO /iwbep/if_message_container, ls_message type scx_t100key, err_msg type string, ls_snwd_so type snwd_so. constants: lc_soitems TYPE string VALUE 'Items'. * Validate whether the current request including the inline SO Item data matches lv_compare_result = io_expand->compare_to( lc_soitems ). * Upon match, access data from IO_DATA_PROVIDER if lv_compare_result EQ /iwbep/if_mgw_odata_expand=>gcs_compare_result-match_equals. io_data_provider->read_entry_data( IMPORTING es_data = ls_so ). * Move header SO data into BAPI structure move-corresponding ls_so to ls_sohdr. * Move SO line items into BAPI table structure loop at ls_so-items into ls_soitem. append ls_soitem to lt_soitem. endloop. CALL FUNCTION 'BAPI_EPM_SO_CREATE' EXPORTING HEADERDATA = ls_sohdr IMPORTING SALESORDERID = lv_so_id TABLES ITEMDATA = lt_soitem RETURN = lt_return . if lt_return is not initial. loop at lt_return into ls_return. err_msg = ls_return-message . endloop.
How To... Build OData Services Using SAP Gateway
June 2015 35
ls_message-msgid = 'SY'. ls_message-msgno = '002'. ls_message-attr1 = err_msg. raise exception type /iwbep/cx_mgw_busi_exception exporting textid = ls_message. else. CALL FUNCTION 'BAPI_EPM_SO_GET_DETAIL' EXPORTING SO_ID = lv_so_id IMPORTING HEADERDATA = ls_sohdr2 TABLES ITEMDATA = lt_soitem2 * RETURN = . move-corresponding ls_sohdr2 to ls_so. ls_so-items = lt_soitem2. copy_data_to_ref( EXPORTING is_data = ls_so CHANGING cr_data = er_deep_entity ). endif. endif. endmethod.
One of the unique aspects of this method is the structure of the data incoming. Since it consists of two entity types, arranged in a parent-‐child nested-‐like structure, a similar structure must be declared to capture such data. This is done by defining a type ty_s_so:
The type ty_s_so consists of a structure of type zcl_z_epm_rkt_mpc=>ts_salesorder (which in turn is of type BAPI_EPM_SO_HEADER) and a table type of made up of structure zcl_z_epm_rkt_mpc=>ts_salesorderitem (which is turn is of type BAPI_EPM_SO_ITEM). A structure variable ls_so is declared using type ty_s_so and used to capture the sales order header data along with the multiple line items passed into the method.
How To... Build OData Services Using SAP Gateway
June 2015 36
Then the data is broken up into the required header and item data structures needed as input for function BAPI_EPM_SO_CREATE. Upon success, the created sales order entity along with its corresponding line items are read and sent back to the consumer in the response body.
8. Activate the implementation. If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
9. Go back to the Class Interface screen.
4.5.2 Implementing Entity Update Creating an implementation for the UPDATE operation can be done using the UPDATE_ENTITY method. For our scenario, we will update a single SalesOrder entry using the SALESORDERS_UPDATE_ENTITY method. 1. On the Class Builder screen for class ZCL_Z_EPM_RKT_DPC_EXT, scroll down to the
SALESORDERS_UPDATE_ENTITY method, place the cursor in the row, and select the Redefine button.
2. Implement the method with the following code.
method SALESORDERS_UPDATE_ENTITY. DATA: lv_id(10) TYPE N, ls_id TYPE bapi_epm_so_id. DATA: ls_headerdata TYPE bapi_epm_so_header, lt_return TYPE TABLE OF bapiret2, ls_return TYPE bapiret2, err_msg TYPE string, lo_message_container TYPE REF TO /iwbep/if_message_container. DATA: ls_message TYPE scx_t100key, lt_keys TYPE /iwbep/t_mgw_tech_pairs. DATA ls_headerdatax TYPE bapi_epm_so_headerx. FIELD-SYMBOLS: <ls_key> TYPE /iwbep/s_mgw_tech_pair. lt_keys = io_tech_request_context->get_keys( ). READ TABLE lt_keys WITH KEY name = 'SO_ID' ASSIGNING <ls_key>. IF sy-subrc EQ 0. lv_id = <ls_key>-value. ENDIF.
How To... Build OData Services Using SAP Gateway
June 2015 37
IF lv_id IS INITIAL. ls_message-msgid = 'SY'. ls_message-msgno = '002'. ls_message-attr1 = 'No Sales Order ID provided'. RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception EXPORTING textid = ls_message. ENDIF. io_data_provider->read_entry_data( IMPORTING es_data = ls_headerdata ). ls_id-so_id = lv_id. " EPM: Sales Order header data fields that can be updated " using the OData service ls_headerdatax-so_id = lv_id. ls_headerdatax-note = 'X'. ls_headerdatax-LIFECYCLE_STATUS = 'X'. ls_headerdatax-BILLING_STATUS = 'X'. ls_headerdatax-DELIVERY_STATUS = 'X'. CALL FUNCTION 'BAPI_EPM_SO_CHANGE' EXPORTING SO_ID = ls_id SOHEADERDATA = ls_headerdata SOHEADERDATAX = ls_headerdatax TABLES RETURN = lt_return . IF lt_return IS NOT INITIAL. LOOP AT lt_return INTO ls_return. err_msg = ls_return-message . ENDLOOP. ls_message-msgid = 'SY'. ls_message-msgno = '002'. ls_message-attr1 = err_msg. RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception EXPORTING textid = ls_message.
How To... Build OData Services Using SAP Gateway
June 2015 38
ENDIF. MOVE-CORRESPONDING ls_headerdata TO er_entity. endmethod.
The BAPI function BAPI_EPM_SO_CHANGE is used to update the data using the SO_ID key passed in. The implementation defines four fields (Note, Lifecycle Status, Billing Status, and Delivery Status) that can be updated by using the ls_headerx structure. Upon success for an Update/PUT operation, updated data is not returned in the response body, which complies with the OData standard for a PUT operation. A HTTP response code of 204 is confirmation that the update operation succeeded.
3. Activate the implementation. If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
4. Go back to the Class Interface screen.
4.5.3 Implementing Entity Delete Creating an implementation for the DELETE operation can be done using the DELETE_ENTITY method. For our scenario, we will delete a single SalesOrder entry using the SALESORDERS_DELETE_ENTITY method. 1. On the Class Builder screen for class ZCL_Z_EPM_RKT_DPC_EXT, scroll down to the
SALESORDER_DELETE_ENTITY method, place the cursor in the row, and select the Redefine button.
2. Implement the method with the following code.
method SALESORDERS_DELETE_ENTITY. DATA: lt_keys TYPE /IWBEP/T_MGW_TECH_PAIRS, ls_key TYPE /IWBEP/S_MGW_TECH_PAIR, ls_so_id type BAPI_EPM_SO_ID, lv_so_id(10) type N. lt_keys = IO_TECH_REQUEST_CONTEXT->GET_KEYS( ). READ TABLE lt_keys with key name = 'SO_ID' INTO ls_key. lv_so_id = ls_key-value. ls_so_id-so_id = lv_so_id. CALL FUNCTION 'BAPI_EPM_SO_DELETE' EXPORTING SO_ID = ls_so_id * TABLES
How To... Build OData Services Using SAP Gateway
June 2015 39
* RETURN = lt_return . endmethod.
The BAPI function BAPI_EPM_SO_DELETE is used to delete a sales order using SO_ID key passed in. Upon success for a DELETE operation, no data is returned. An HTTP response code of 204 is confirmation that the Delete operation succeeded.
3. Activate the implementation. If you get any warnings about errors, recheck the code, correct any mistakes, and then re-‐activate.
4. Go back to the Class Interface screen and then back again to return to the main Service Builder screen.
How To... Build OData Services Using SAP Gateway
June 2015 40
4.6 Implementing Delta Token Support In SMP 3.0 the responsibility of Delta tracking has been relegated to the backend system itself. SAP Gateway, starting from version 2.0 SP07, provides delta query support. Delta querying means “give me all entities that were created/changed/deleted since I last asked”. In other words, the delta query protocol defines a pull-‐model protocol for clients to obtain changes in an entity set. The methods GET_ENTITYSET and GET_ENTITYSET_DELTA are used to enable delta handling via Gateway. GET_ENTITYSET_DELTA will be called when the client provides a Delta Token in the request. When the client requests the entity set the first time the entire collection is returned, but along with this collection a Delta Token is returned. This Delta Token is normally a date time stamp combined with a GUID. This Delta Token must be persisted by the client and then provided during the next call to the entity set and it is here that the GET_ENTITYSET_DELTA function is called instead of the GET_ENTITYSET. So now we understand the mechanism, but how do we implement GET_ENTITYSET_DELTA and keep track of changes that occur in the backend. It turns out in an SAP ABAP system that there is not just one way of doing this and depending on the type of object being tracked the approach will change. Currently there are two approaches that might be considered for delta handling: 1) Using Delta Request Log Component 2) Using Syclo xChange Framework The implementation details are explained in the another H2G.