Sie sind auf Seite 1von 35

The new SAP NetWeaver Gateway Service

Builder: Build new OData Services in 3 Quick


Steps
Posted by Thomas Meigen in SAP Gateway on Sep 7, 2012 5:59:50 PM

Tweet

With this blog we would like to introduce the new Service Builder in SAP NetWeaver Gateway
and its various options for building OData services for SAP NetWeaver and SAP Business Suite
data.

Why the need to build OData services?


OData is an evolving standard for RESTful service for exposing business data to any kind of
app, whether it runs natively on a smart device or is a flexible, HTML based client. Now that
OData also has entered the OASIS standardization process and with a growing number of
software vendors endorsing it, it could become the Lingua Franca for bringing business data
to any Internet device.

Consuming OData in any kind of app is fairly easy. OData SDKs are available for all relevant
client technology and for the most important ones there are already dedicated developer
tools, which help any kind of developer to jump-start his app development by consuming
available OData services. To get started with OData consumption for SAP NetWeaver
Gateway, SDN includes several toolkits for instance for iOS, Android, JSE, PHP or HTML5.

What easily gets overlooked is the fact, that nearly always the right OData service first has to
be built before it can be consumed. The number of out-of-the-box OData services is and may
remain limited. When you think about it, this quite logical, because OData services by nature
are fine granular and mostly tailored to the use case. In that sense they are quite different
from comprehensive Enterprise Services in A2A scenarios, where resources like bandwidth,
memory and CPU power are less critical. Learnings from app development projects show that
up to 50% of development time can go into building the right OData service.

Introducing the Service Builder


Gateway Service Builder (transaction "SEGW") is available as of Release 2.0 Support Package
4/5 and it greatly accelerates the OData service development process. In many cases you
don't even need to write a single line of ABAP code - unless of course you prefer to do so. It is
no longer mandatory that you have deep ABAP OO skills. And the development time for a
new OData service can be reduced to hours rather than days.

In Service Builder you need to do 3 main steps to build an OData service:


1. Define or import the data model
2. Implement or generate the runtime logic for the service operations
3. Activate and run the service

The picture below shows the various options that are covered in SEGW:

Step 1: Define the data model


First, when building a mobile or Web app you determine which SAPdata you need. Then you
retrieve the data where they usually are: somewhere in the SAP Business Suite. We call this
"outside-in approach". Gateway Service Builder is optimized (but not limited) for this
approach.

For the definition of a new data model you will find different options inside SEGW. You can
define all elements of the OData service step by step using the various editors within the
transaction. If your data model is similar to an existing data structure (like an RFC or BAPI)
inside of the DDIC, you can also import that structure. Alternatively, if you already have an
existing OData model definition in appropriate EDMX format, you can import that from a file.
At any time, you can check the consistency of the data model and SEGW will show you
existing issues and guide you there. Also, as soon as you have a valid data model you can
already activate the service and display the service document and the metadata in a
browser.
Things become very interesting, when you have the right business framework in your SAP
Business Suite landscape. If there is any data object available which contains the data that
you are looking for, you actually can ask SEGW to generate an OData service from that
object. Guided by wizards you simply select the data (entity types and properties) that you
need and rename ("redefine") them to make them look OData style. Redefinition is already
supported for BW Easy Query, SPI, GenIL and BOL with thousands of well-defined business
objects. With the redefine option you will also get the implementation of the service
operations for free and can immediately execute the resulting OData service.

Step 2: Implement the service operations


Having the right data model definition you then need to provide the runtime logic for the
different service operations, usually CRUDQ. Also for this Gateway Service Builder offers you
several paths. For both the Model Provider Class (MPC) and the Data Provider Class (DPC)
Service Builder always generates a base class, that will be overwritten during the next
generation step, and an extension class (name ends with "_EXT"), where you can put your
own code extensions. You now can write the ABAP code for the service operations into the
stub classes that SEGW generates.

But perhaps already one of the many thousand RFCs or BAPIs in the SAP Business Suite
already does the right job. Then you can map the RFC or BOR operations to your data model.
In that case SEGW generates the entire ABAP runtime logic.
As soon as you have a valid data model you can already activate the service and check out
the service document and the metadata.

Step 3: Publish and run the OData service


Last step in the process is that you register, activate and run the OData services. Would be
great to do all this from SEGW, right? This is how SEGW now behaves. Gateway lets you have
various different deployment options and the service could be registered on the Suite
backend but also in an Gateway hub. Therefore from SEGW you can navigate to the Activate
and Maintain Service transaction on the right system and from there to all the other useful
functions, like Service Explorer, Gateway Client and Error Log.
The truth is in the code
So far you haven't seen a single line of code in this blog, right? Our objective with the Service
Builder was to provide comprehensive support for building services in a declarative way or by
re-using existing business objects in the SAP system. However, we know that there always
are limitations to what can be declared and generated. Advanced OData features may need
to be implemented manually or certain operations are not available in a redefined business
object. Therefore the result of what you do in Service Builder will always end up in those
ABAP classes mentioned above, which are based on the powerful OData Channel
programming model of SAP NetWeaver Gateway. So, if you want to do some drill-down to
understand what is going on during service execution or if, for whatever reason, you want to
tweak the code, you can just go ahead and do it. This way you get great development
support and still retain the freedom to decide the ideal development approach.

Building OData services has never been easier


Service Builder is a new transaction in available as of SP4 and and further enhanced in SP5 to
make life easier for experienced ABAP developers and SAP experts who are less into writing
code. It is now available as part of the software component IW_BEP for SAP NetWeaver
Gateway SP5 and can be deployed as an add-on to SAP NetWeaver 7.0 or higher. We will
publish additional blogs in the coming weeks an months and drill down into special topics. In
any case, try it out and let us know what you like or dislike about this new developer tool.

We can't wait to hear your views and suggestions.


Step-by-step guide to build an OData Service
based on RFCs Part 1
Posted by Volker Drees in volker.drees on Oct 26, 2012 11:43:50 AM
Tweet

Hello fellow OData Service developers out there.

When it comes to OData Service development with SAP NetWeaver Gateway a very typical
use case is to build a service that is based on an RFC module (or a set of RFC modules) e.g.
for a List / Detail application. For such a scenario there are dozens of RFC modules (BAPIs)
available in the SAP standard that can be used. And of course you can also build and
consume your own (Z-)RFC modules if the existing modules dont satisfy your needs...

For additional information regarding the Service Builder please also see Thomas Meigens
Blog: The new SAP NetWeaver Gateway Service Builder: Build new OData Services in 3 Quick
Steps

In this Step-by-step Guide we will build an OData Service that consumes two RFC modules
from the EPM (Enterprise Procurement Model) demo content. From this EPM demo content we
pick two BAPIs that retrieve the list and detail of Sales Orders / Line Items. The data model is
pretty simple. We have one entity for the Sales Order header data, and one entity for the
Sales Order Line Item.

The two BAPIs that we will use in our service


are: BAPI_EPM_SO_GET_LIST and BAPI_EPM_SO_GET_DETAIL
This guide is based on SAP NetWeaver Gateway 2.0 SP5. We will be mainly using the SAP
NetWeaver Gateway Service Builder for the service creation. The Service Builder allows
us to build our service without writing a single line of code (although you still can do coding
if you want).

In this first part (1) we will build a Meta Model of the service. In the second part (2) we will
perform the service implementation.

So lets get started.

1. Create a new project ZGW100_XX_SO (SO stands for Sales Order). XX is just a
placeholder for a group number and GW100 indicates the course number as the screen
shots were taken from the GW100 training course material that I have created.
2. Create the first entity by importing an RFC interface. For this right-click on Data Model and
choose Import -> RFC/BOR Interface

3. Enter the following values in the wizard and then choose Next:

Entity Type Name SalesOrder


Target System Local
Data Source Type Remote Function Calls
Data Source Name BAPI_EPM_SO_GET_LIST
4. Expand the SOHEADERDATA node and select the following fields:
SO_ID, NOTE, BUYER_ID, BUYER_NAME, CURRENCY_CODE, GROSS_AMOUNT, NET_AMOUNT,
TAX_AMOUNT
Note that SOHEADERDATA is not selected. Choose Next.

5. In the first line, SO_ID, select the field Is Key and choose Finish:
6. Create the second entity again by importing an RFC interface. Right-click Data Model and
choose Import -> RFC/BOR Interface

7. Enter the following values in the wizard and choose Next:

Entity Type Name SalesOrderItem


Target System Local
Data Source Type Remote Function Calls
Data Source Name BAPI_EPM_SO_GET_LIST
8. Expand the SOITEMDATA node and select the following fields:
SO_ID, SO_ITEM_POS, PRODUCT_ID, NOTE, CURRENCY_CODE, GROSS_AMOUNT,
NET_AMOUNT, TAX_AMOUNT, QUANTITY, QUANTITY_UNIT
Note that SOITEMDATA is not selected. Choose Next.

9. In the first and second line, SO_ID, SO_ITEM_POS, select the field Is Key and choose Finish:
Now our project has 2 entities one for the Sales Order and one for the Sales Order Line
Item. As a next step we create entity-sets out of these entities.

1. Expand the node Data Model and double-click Entity Sets:

2. Click the Create button twice to add two new lines to the table:
3. Enter the following values:

Name Entity Type Name


SalesOrderCollection SalesOrder
SalesOrderItemCollection SalesOrderItem

4. Choose Save:

Now the basic definition of the Model is done. As a next step we can generate the necessary
runtime artifacts.

1. Choose the Generate pushbutton:

2. Leave the default values and choose Enter:


Please note the Technical Service Name ZGW100_XX_SO_SRV is equal to the External Service
Name required to consume this service later on.

3. Choose Local Object:

4. Verify that the runtime objects have been generated successfully:


Now we can Register and Activate the Service.

1. Double-click Service Maintenance:

2. Select system ZME and choose the Register button. Please note that the entries listed here
depend on the System Alias configuration you have done in the SAP NetWeaver Gateway
Implementation Guide (IMG). In a local deployed environment (Backend and Hub components
deployed on the same box) you might also find LOCAL with the RFC destination NONE
here.

3. Confirm the warning message displayed in the popup:


4. Press F4 to select the system alias. Select ERP_EMEA from the input help. Please note that
you wont get any popup if there is only 1 System Alias maintained. As mentioned above,
depending on the deployment method and IMG configuration you possibly see an alias
LOCAL instead of the ones shown in the screen shot:

5. Confirm the Select System Alias popup:

6. Leave the default values and enter $tmp as the package and choose Enter:
The External Service Name is defaulted with the Technical Service Name from the Generation
Step.

7. Verify that the service has been registered and activated successfully:

Now we can run our service the first time. Please note that weve only maintained the basic
model data so far. As a consequence we can access the metadata of the service, but not yet
any business data (that will come in part 2).

1. Open a new window, start transaction /IWFND/GW_CLIENT.

2. Enter URI: /sap/opu/odata/sap/ZGW100_XX_SO_SRV/$metadata and choose Execute:


ZGW100_XX_SO_SRV is the External Service Name that was registered before.

So we are done for the moment. We have created a Service Builder Project with two entities
and two entity-sets. We have generated the runtime artifacts and registered and activated
our OData service. In part 2 we will map the data provider to bring life into our OData service.
Step-by-step guide to build an OData Service
based on RFCs Part 2
Posted by Volker Drees in volker.drees on Oct 26, 2012 11:44:38 AM
Tweet

Hello again.

In the first part (1) we have created a service that consists of two entities (Sales Order and
Sales Order Line Item) and two related entity-sets. The runtime artifacts have been
generated and the OData service has been registered and activated.
In this part (2) we will map both entity-sets to the related data providers in our case the 2
EPM BAPIs.
When it comes to data provider mapping / implementation of OData services you usually
start with the Query method as this is a typical entry point when consuming a service. In our
case we will first enable the query: provide me all Sales Orders that exist. In a real business
case you would probably make some filtering mandatory to not overload the backend
system. But lets keep it simple for the time being

1. As mentioned we will start with the Query method for the SalesOrderCollection entity-set.
Expand the node Service Implementation -> SalesOrderCollection and right-
click GetEntitySet (Query) and select Map to Data Source:

2. In the map to data source window, enter the following values and choose Enter:
Target System Local
Data Source Type Remote Function Call
Data Source Name BAPI_EPM_SO_GET_LIST
3. The mapping has already done because the data model has been built based on the same
RFC interface. For each property, set the Mapping Direction to Output. Choose Enter:

Now we can move on and do the mapping for the Read operation (GetEntity) of the
SalesOrderCollection.
1. Right-click GetEntity (Read) and select Map to Data Source:
2. In the Map to Data Source dialog box, enter the following values and choose Enter:
Target System Local
Data Source Type Remote Function Call
Data Source Name BAPI_EPM_SO_GET_DETAIL

3. This time there are no default mapping settings because the data model has been defined
based on a different RFC module.
Expand the HEADERDATA node from the tree on the right-hand side:
4. Drag&drop the following fields from the right-hand tree to the Data Source
Parameter column of the grid in the middle of the screen:
RFC Field (right hand side) Entity Property
SO_ID SoId
NOTE Note
BUYER_ID BuyerId
BUYER_NAME BuyerName
CURRENCY_CODE CurrencyCode
GROSS_AMOUNT GrossAmount
NET_AMOUNT NetAmount
TAX_AMOUNT TaxAmount

In any Read Operation we also need to provide the primary key of the underlying entity as an
input parameter. For this we have to manually add a new line to the mapping screen.

1. Choose the Append Row pushbutton:


2. On the new line press F4 to select the entity set property. Double-click SoId to select the
entry:

3. Expand the SO_ID node from the tree on the right-hand side:

4. Drag&Drop the RFC field SO_ID (from node SO_ID) to the newly-created line:
5. This performs the mapping on the input parameter (Sales Order ID to fetch the Sales Order
details):

Now we can move on with mapping the Query operation for the Sales Order Item entity-set

1. Expand the node Service Implementation -> SalesOrderItemCollection and right-


click GetEntitySet (Query) and selectMap to Data Source:

2. In the Map to Data Source dialog box, enter the following values and choose Enter:

Target System Local


Data Source Type Remote Function Call
Data Source Name BAPI_EPM_SO_GET_DETAIL
3. There is again no default mapping because the data model has been built based on a
different RFC module. Expand the ITEMDATA node from the tree on the right-hand side:

4. Drag&drop the following fields from the right-hand tree to the Data Source
Parameter column of the grid in the middle of the screen:

RFC Field (right hand side) Entity Property


SO_ID SoId
SO_ITEM_POS SoItemPos
PRODUCT_ID ProductId
NOTE Note
CURRENCY_CODE CurrencyCode
GROSS_AMOUNT GrossAmount
NET_AMOUNT NetAmount
RFC Field (right hand side) Entity Property
TAX_AMOUNT TaxAmount
QUANTITY Quantity
QUANTITY_UNIT QuantityUnit

5. In the Direction Column set all fields to Output. Choose Enter:

6. Choose Append Row button:

7. From the input help, select SoId for the new line:

8. Expand the SO_ID node from the right-hand tree:


9. Drag&drop the RFC field SO_ID (from node SO_ID) to the newly created line:

Now we are done with the data provider mapping (at least for the Query and Read operations
we need). Now we can re-generate the runtime artifacts and run our OData service.

1. Choose the Generate pushbutton:

2. Verify that the runtime objects have been generated successfully:

3. Start the Gateway Client (Transaction /IWFND/GW_CLIENT) in a separate window to run


the service. Provide the following URI to get the Sales Order Collection. This executes the
query method of the Sales Order entity-set:
/sap/opu/odata/sap/ZGW100_XX_SO_SRV/SalesOrderCollection
4. Choose any sales order entry and use the URI to navigate to the sales order detail, for
example:
/sap/opu/odata/sap/ZGW100_XX_SO_SRV/SalesOrderCollection('0500000001')

5. Get the related sales order line items via the following URL:
/sap/opu/odata/sap/ZGW100_XX_SO_SRV/SalesOrderItemCollection/?$filter=SoId eq
'0500000001'
To navigate from the Sales Order entity to the related line items (Entity-Set), you need to
construct the URI yourself. In the next part (3) you will see how to define an association and a
navigation property between the two Entities.
Step-by-step guide to build an OData Service
based on RFCs Part 3
Posted by Volker Drees in volker.drees on Oct 26, 2012 11:45:07 AM
Tweet

Thanks for sticking to this multi-part step-by-step guide.

Looking into this part (3) means that you have successfully completed the first part (1) and
the second part (2) and you are now curious to see how our EPM OData Service will be
extended with an Association and a Navigation Property. This will allow us to navigate from
the Sales Order to the related Sales Order Line Items by using a link instead of manually
putting a filter together. Furthermore this also allows us to use the $expand statement to
fetch the Sales Order together with all Sales Order Line Items in one http call.

We are still in the Service Builder and enhancing our project that we created in part 1 and
extended in part 2.

1. Double-click Associations:

2. Choose the Create pushbutton:

3. Enter the following values for the Association and choose Enter:

Name SalesOrderSalesOrderItems
Principal Entity* SalesOrder
Principal Entity Cardinality* 1
Dependent Entity* SalesOrderItem
Dependent Entity Cardinality* M
*) This field has an input help

Now we will Create a referential constraint for the association


1. Expand the Associations node and the SalesOrderSalesOrderItems node and double-
click Referential Constraints:

2. Choose the Create pushbutton:

3. Enter the following values and choose Enter:

Principal Key* SoId


Dependent Property* SoId
*) This field has an input help

Now we create an association set for the association

1. Double-click Association Sets:


2. Choose the Create pushbutton:

3. Enter the values and choose Enter:

Name SalesOrderSalesOrderItems
Association* SalesOrderSalesOrderItems
*) This field has an input help

And finally we create a navigation property based on the referential constraint

1. Expand Data Model -> Entity Types -> SalesOrder and double-click Navigation Properties:
2. Choose the Create pushbutton:

3. Enter the following values and choose Enter:

Name SalesOrderItems
Relationship Name* SalesOrderSalesOrderItems
*) This field has an input help

Now we need to re-generate the runtime objects and were then ready to test the service

1. Choose the Generate pushbutton:

2. Verify that the runtime objects have been generated successfully:


3. Start the Gateway Client (Transaction /IWFND/GW_CLIENT) in a separate window to run
the service. Provide the following URI to get the metadata for the service:
/sap/opu/odata/sap/ZGW100_XX_SO_SRV/$metadata

The Sales Order collection now includes a navigation property.

4. When you now select a sales order entry using


/sap/opu/odata/sap/ZGW100_XX_SO_SRV/SalesOrderCollection('0500000001'), for
example, you can simply add the navigation link /SalesOrderItems to navigate to the line
items without having to set a filter yourself:
5. And finally you can use $expand to read all sales order items for a given sales order in a
single http call.
Simply provide the following URI:
/sap/opu/odata/sap/ZGW100_XX_SO_SRV/SalesOrderCollection('0500000001')/?
$expand=SalesOrderItems

The $expand statement is handled by the framework (no additional implementation is


required). Since the framework does not know that both entities can be obtained using a
single RFC call, it executes two calls to the underlying BAPI. This can be improved by
manually implementing (re-defining) the GET_EXPANDED_ENTITY method.

So we are done. The Service is up and running.

I hope you enjoyed creating and consuming an OData Service that is based on RFC modules.

Das könnte Ihnen auch gefallen