Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
UweFetzer_se38
Active Contributor


This year, just a week before I've started my wonderful vacations in Barcelona and Alcúdia, I had again the pleasure to hold a session at SAP Inside Track Hamburg. Because I'm not able to provide the slides (I haven't used any) I was asked to blog about it. (to satisfy someone: this means to "write a blog post" :wink: )

The Motivation


One of my current customers is implementing a new E-commerce shop and I'm responsible for the connection to the backend SAP ERP system. "Yea, again a SAP Gateway project" just came into my mind as soon as I've heard about it 🙂 A quick look into "System -> Status" and I realized that they are on ERP 6.0 Ehp 0 (Zero) -> no Gateway installed.

The Options



  1. upgrade the system to a higher Enhancement Package so SAP GW is part of the standard installation

  2. install SAP GW as Add-On

  3. something completely different


Option 1.) was completely out of budget. Sure, they have to do it sometimes in the near future, but not now and not for this reason.

For option 2.) a question came into my mind, which I was not able to answer: what happens in a later EHP upgrade, where SAP GW is part of the standard, if we already had installed SAP GW as Add-On? Will we get into trouble?

The Solution


If you know a bit of my background (I'm a little RESTifarian ), you will not be surprised that I've choosen ADL (Alternative Dispatcher Layer, by dj.adams ) and zJSON (ABAP JSON document class, by me) to solve this problem. Open Source #ftw ! Links: see Appendix

 

SAP's new claim is "SIMPLE". And yes: ADL + zJSON is simple. It's so simple, that I'm using it even for prototyping if SAP GW IS installed (because ie. the cleansing behind you is much easier).

 

Edit: please concider that you need an additional user license for the (anonymous) ICF user.


 

The Data


To make the demo a bit (more) interesting, I've used a DDL view instead of a table as data source:

@AbapCatalog.sqlViewName: 'YSITHH_SO'


define view ysitHHSalesOrder as select from snwd_so as so


inner join snwd_bpa as bpa on so.buyer_guid = bpa.node_key {


  key so.so_id as id,


  bpa.bp_id as business_partner_id,


  bpa.company_name,


  substring( bpa.company_name, 1, 10 ) as company_short,


  case bpa.bp_role


    when '01' then 'Customer'


    when '02' then 'Supplier'


    else 'undefined'


  end as business_partner_role,


  case so.billing_status


    when ' ' then 'unpaid'


    else 'paid'


  end as billing_status,


  @Semantics.currencyCode so.currency_code,


  @Semantics.amount.currencyCode: 'currency_code' so.gross_amount


}



(for documentation link on DDL sources and the new openSQL syntax, see Appendix)

Test report

DATA salesorders TYPE STANDARD TABLE OF ysithhsalesorder.


SELECT * FROM ysithhsalesorder


  INTO TABLE @salesorders.


cl_demo_output=>display( salesorders ).



Result


The JSON document


To translate the data in JSON format I've used my JSON document class.

DATA salesorders TYPE STANDARD TABLE OF ysithhsalesorder.


SELECT * FROM ysithhsalesorder


  INTO TABLE @salesorders.


cl_demo_output=>display_json( zcl_json_document=>create_with_data( salesorders )->get_json( ) ).



(you've noticed the method chaining? I like it. But don't overuse it, please)

Result


The Call


Now to the REST call: the ADL implementation.

We have to create the REST dispatcher (or use an existing one) and the REST resource for the order data.

The Dispatcher

CLASS ysithh_dispatcher_test DEFINITION


  PUBLIC


  INHERITING FROM y_adl_disp_base


  FINAL


  CREATE PUBLIC .


  PUBLIC SECTION.


    METHODS if_http_extension~handle_request REDEFINITION.


  PROTECTED SECTION.


  PRIVATE SECTION.


ENDCLASS.


CLASS YSITHH_DISPATCHER_TEST IMPLEMENTATION.


  METHOD if_http_extension~handle_request.


    handler( p = '^/SalesOrder' h = 'YSITHH_SALESORDER_TEST' ).


    dispatch( server ).


  ENDMETHOD.


ENDCLASS.



Don't forget to enter the dispatcher class into the ICF path via transaction SICF





The Resource

CLASS ysithh_salesorder_test DEFINITION


  PUBLIC


  INHERITING FROM y_adl_res_base


  FINAL


  CREATE PUBLIC .


  PUBLIC SECTION.


    METHODS get


      IMPORTING matches TYPE stringtab.


  PROTECTED SECTION.


  PRIVATE SECTION.


ENDCLASS.


CLASS ysithh_salesorder_test IMPLEMENTATION.


  METHOD get.


    DATA salesorder TYPE STANDARD TABLE OF ysithhsalesorder.


    SELECT * FROM ysithhsalesorder


      INTO TABLE @salesorder.


    response->set_cdata( zcl_json_document=>create_with_data( salesorder )->get_json(  ) ).


    response->set_header_field(


      EXPORTING


        name = 'Access-Control-Allow-Origin'    " Name of the header field


        value = '*'    " HTTP header field value


    ).


  ENDMETHOD.


ENDCLASS.



The Test

For a test of the service just call the resource in a browser of your choice: http://host:port/sap/bc/ysithh_test/SalesOrder

Viewed with Chrome plug-in "JSONview"


The App


Now we are able to consume the data for example in an UI5 table.

index.html

<!DOCTYPE HTML>


<html>


<head>


<meta http-equiv="X-UA-Compatible" content="IE=edge">


<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>


<script src="resources/sap-ui-core.js"


id="sap-ui-bootstrap"


data-sap-ui-libs="sap.ui.commons"


data-sap-ui-theme="sap_bluecrystal">


</script>


<!-- add sap.ui.table,sap.ui.ux3 and/or other libraries to 'data-sap-ui-libs' if required -->


<script>


sap.ui.localResources("sithh_test");


var view = sap.ui.view({id:"idmain1", viewName:"sithh_test.main", type:sap.ui.core.mvc.ViewType.XML});


view.placeAt("content");


</script>


</head>


<body class="sapUiBody" role="application">


<div id="content"></div>


</body>


</html>



main.view.xml

<core:View xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc"
xmlns:commons="sap.ui.commons"
xmlns:m="sap.m"
xmlns="sap.ui.table"
controllerName="sithh_test.main" xmlns:html="http://www.w3.org/1999/xhtml">
<Table
id="tt"
rows="{/itab}"
title="Table Example">
<columns>
<Column>
<label>
<commons:Label text="ID" />
</label>
<template>
<commons:TextField value="{id}" />
</template>
</Column>
<Column>
<label>
<commons:Label text="Company" />
</label>
<template>
<commons:TextField value="{company_short}" />
</template>
</Column>
<Column>
<label>
<commons:Label text="Role" />
</label>
<template>
<commons:TextField value="{business_partner_role}" />
</template>
</Column>
<Column>
<label>
<commons:Label text="Status" />
</label>
<template>
<commons:TextField value="{billing_status}" />
</template>
</Column>
<Column>
<label>
<commons:Label text="Currency" />
</label>
<template>
<commons:TextField value="{currency_code}" />
</template>
</Column>
<Column>
<label>
<commons:Label text="Value" />
</label>
<template>
<commons:TextField value="{gross_amount}" />
</template>
</Column>
</columns>
</Table>
</core:View>








main.controller.js

sap.ui.controller("sithh_test.main", {
onInit: function() {
var oModel = new sap.ui.model.json.JSONModel(
'http://se38-d7x-1.se38.local:8000/sap/bc/ysithh_test/SalesOrder'
);
sap.ui.getCore().setModel(oModel);
},
});







The Result



Appendix


If you wonder: SAP has changed the name of "SAP Netweaver Gateway". It is now just "SAP Gateway"

ADL

Source: https://github.com/qmacro/ADL

Documentation: http://scn.sap.com/people/dj.adams/blog/2009/09/21/a-new-rest-handler-dispatcher-for-the-icf

JSON Document Class

Source: https://github.com/se38/zJSON/wiki/Usage-zJSON

Open UI5

http://sap.github.io/openui5/

DDL

http://scn.sap.com/community/abap/eclipse/blog/2014/02/04/new-data-modeling-features-in-abap-for-han...

New Open SQL Syntax

http://help.sap.com/abapdocu_740/en/index.htm?file=ABENNEWS-740_SP05-OPEN_SQL.htm

You can reach me via Twitter or G+

9 Comments
Labels in this area