`
JerryWang_SAP
  • 浏览: 1026202 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

30分钟用Restful ABAP Programming模型开发一个支持增删改查的Fiori应用

阅读更多

2016年时,Jerry曾经写过一系列关于SAP Fiori Smart Template(现在更名为Fiori Elements了)的博客,介绍了所谓的MDD开发方法论 - Metadata Driven Development,即通过开发维护了对应annotation(注解)的CDS view,结合SAP WebIDE,能够花费最少的编程代价,就能够在短时间内获得一个支持增删改查的Fiori应用。

这个系列的博客集可以在Jerry这篇公众号文章里获得:Jerry的通过CDS view + Smart Template 开发Fiori应用的blog合集

三年的时间过去了,ABAP在不断向前进化,如今我们有了新的编程模型:Restful ABAP Programming模型,简称为RAP模型。该模型定义了一套架构体系,应用开发人员能够凭借其来高效地进行应用的端到端开发,这种应用具有与生俱来的Restful特质,能充分利用HANA平台的强大计算能力,支持云环境和Fiori UX。

 

 

RAP模型的三大支柱:

  • Business Service
  • Core Data Service
  • Behavior Definition

 

 

下面请跟着Jerry一起,通过一个实际的例子,了解一下这种全新的通过Restful ABAP Programming模型进行Fiori应用开发的步骤吧。

Jerry还是沿用传统ABAP On-Premises编程培训教材里使用过的经典的SFLIGHT模型来作为底层数据库存储。

(1)首先创建一个数据库表ZTRAVEL_JERRY:(如果想复制这段源代码,请点击文末的“阅读原文”获得)

@EndUserText.label : 'Database table for travel data XXX'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #LIMITED
define table ztravel_jerry {
  key client      : abap.clnt not null;
  key travel_id   : /dmo/travel_id not null;
  agency_id       : /dmo/agency_id;
  customer_id     : /dmo/customer_id;
  begin_date      : /dmo/begin_date;
  end_date        : /dmo/end_date;
  @Semantics.amount.currencyCode : 'ztravel_jerry.currency_code'
  booking_fee     : /dmo/booking_fee;
  @Semantics.amount.currencyCode : 'ztravel_jerry.currency_code'
  total_price     : /dmo/total_price;
  currency_code   : /dmo/currency_code;
  description     : /dmo/description;
  created_by      : syuname;
  created_at      : timestampl;
  last_changed_by : syuname;
  last_changed_at : timestampl;

}

 

 

因为我们在ABAP Development Tools里无法用事务码SE16手动往这张表里插入数据,所以我创建一个ABAP类,用ABAP代码往这个表里插入三条数据。

 

 

按F9执行这个ABAP类,然后看到三条数据成功插入了:

 

 

(2) 我们最终的目的是创建一个支持对这张表进行增删改查的Fiori应用,而Restful ABAP Programming模型的三大支柱之一为Core Data Service,因此我们首先得有基于数据库表ZTRAVEL_JERRY的CDS view.

所以我首先创建一个CDS view:

@AbapCatalog.sqlViewName: 'ZVI_TRAVEL'
@AbapCatalog.compiler.compareFilter: true
@AbapCatalog.preserveKey: true
@AccessControl.authorizationCheck: #CHECK
@EndUserText.label: 'Travel data - XXX'
define root view ZI_TRAVEL_JERRY

 as select from ztravel_jerry as Travel

 /* Associations */
 association [0..1] to /DMO/I_Agency   as _Agency   on $projection.agency_id = _Agency.AgencyID
 association [0..1] to /DMO/I_Customer as _Customer on $projection.customer_id = _Customer.CustomerID
 association [0..1] to I_Currency      as _Currency on $projection.currency_code = _Currency.Currency
 {
  key travel_id,
     agency_id,
     customer_id,
     begin_date,
     end_date,
     @Semantics.amount.currencyCode: 'currency_code'
     booking_fee,
     @Semantics.amount.currencyCode: 'currency_code'
     total_price,
     @Semantics.currencyCode: true
     currency_code,
     description,

/*-- Admin data --*/
     @Semantics.user.createdBy: true
     created_by,
     @Semantics.systemDateTime.createdAt: true
     created_at,
     @Semantics.user.lastChangedBy: true
     last_changed_by,
     @Semantics.systemDateTime.lastChangedAt: true
     last_changed_at,

     /* Public associations */
     _Agency,
     _Customer,
     _Currency
}        

 

 

然后创建一个projection view,将该view的字段有选择性地暴露出来。

@EndUserText.label: 'Travel projection view - Processor'
@AccessControl.authorizationCheck: #NOT_REQUIRED

@UI: {
 headerInfo: { typeName: 'Travel', typeNamePlural: 'Travels', title: { type: #STANDARD, value: 'TravelID' } } }

@Search.searchable: true

define root view entity ZC_TRAVEL_JERRY as projection on ZI_TRAVEL_JERRY {
 @UI.facet: [ { id:              'Travel',
                purpose:         #STANDARD,
                type:            #IDENTIFICATION_REFERENCE,
                label:           'Travel',
                position:        10 } ]

 @UI: {
     lineItem:       [ { position: 10, importance: #HIGH } ],
     identification: [ { position: 10, label: 'Travel ID [1,...,99999999]' } ] }
 @Search.defaultSearchElement: true
 key travel_id          as TravelID,

 @UI: {
     lineItem:       [ { position: 20, importance: #HIGH } ],
     identification: [ { position: 20 } ],
     selectionField: [ { position: 20 } ] }
 @Consumption.valueHelpDefinition: [{ entity : {name: '/DMO/I_Agency', element: 'AgencyID'  } }]

 @ObjectModel.text.element: ['AgencyName'] ----meaning?
 @Search.defaultSearchElement: true
 agency_id          as AgencyID, _Agency.Name       as AgencyName,

 @UI: {
     lineItem:       [ { position: 30, importance: #HIGH } ],
     identification: [ { position: 30 } ],
     selectionField: [ { position: 30 } ] }
 @Consumption.valueHelpDefinition: [{ entity : {name: '/DMO/I_Customer', element: 'CustomerID'  } }]

 @ObjectModel.text.element: ['CustomerName']
 @Search.defaultSearchElement: true
 customer_id        as CustomerID,

 @UI.hidden: true
 _Customer.LastName as CustomerName,

 @UI: {
     lineItem:       [ { position: 40, importance: #MEDIUM } ],
     identification: [ { position: 40 } ] }
 begin_date         as BeginDate,

 @UI: {
     lineItem:       [ { position: 41, importance: #MEDIUM } ],
     identification: [ { position: 41 } ] }
 end_date           as EndDate,

 @UI: {
     lineItem:       [ { position: 50, importance: #MEDIUM } ],
     identification: [ { position: 50, label: 'Total Price' } ] }
 @Semantics.amount.currencyCode: 'CurrencyCode'
 total_price        as TotalPrice,

 @Consumption.valueHelpDefinition: [{entity: {name: 'I_Currency', element: 'Currency' }}]
 currency_code      as CurrencyCode,

 @UI.identification: [ { position: 60, label: 'Remarks' } ]
 description as Description,

 @UI.hidden: true
 last_changed_at    as LastChangedAt

 }        

大家可以注意到,这个projection view里包含了很多@UI注解,作用和Fiori Elements一样,作为元数据,告诉对应的渲染框架,运行时这些字段应该以什么样的方式渲染在Fiori UI上。

 

 

(3) 现在三大支柱之一的Core Data Service已经就位了,接下来我们基于前一步得到的projection view创建Business Service. 选中projection view,右键选择New Service Definition:

 

 

这个服务定义的第一条记录,就是通过ABAP expose关键字把projection view ZC_TRAVEL_JERRY暴露出来,模型名称为TravelProcessor:

 

 

@EndUserText.label: 'Service Defintion for ZC_Travel_JERRY'
define service ZUI_C_TRAVEL_JERRY {
  expose ZC_TRAVEL_JERRY as TravelProcessor;
  expose /DMO/I_Customer as Passenger;
  expose /DMO/I_Agency as TravelAgency;
  expose /DMO/I_Airport as Airport;
  expose I_Currency as Currency;
  expose I_Country as Country;
}

然后基于这个Service Definition创建一个Service Binding,可以简单把Service Binding理解成Service Definition的一个实例:

 

 

 

 

 

Service Binding创建完毕后,点击Activate激活:

 

 

之前Service Definition里用expose关键字暴露并指定成的模型TravelProcessor此时就可见了,双击:

 

 

双击后会自动打开一个链接,一个Fiori应用就呈现在我们眼前了。我们没有进行一行的JavaScript web编程,就得到了一个专业的支持高级搜索的Fiori应用,能查看底层数据库表ZTRAVEL_JERRY的内容。

 

 

(4) 至此我们已经了解了Restful ABAP Programming模型的前两大支柱,还剩下Behavior Definition. 既然RAP的口号是打造具有Restful特性的应用,但到目前为止我们还没有感受到RAP对Restful的支持,这有待Behavior Definition来完成。

选中之前创建的CDS view,创建一个新的Behavior Definition:

 

 

实现类型指定为Managed:

 

 

我们可以看到这个Behavior Definition的定义里,又多了一些新的ABAP关键字。这个Behavior Definition负责定义底层模型的Transaction Behavior,即代码第18到20行的create,update,delete.

 

 

当然增删改查的功能光定义不行,还得创建其对应的实现。上图Definition中已经指定了实现这些行为的ABAP类名称为ZCL_BP_I_TRAVEL_M_JERRY. 为此,右键选择New Behavior Implementation:

 

 

创建这个特殊的ABAP实现类:

 

 

这个实现类里面也不需要开发人员手动编写代码来完成对底层数据库表的增删改查操作——既然能称之为一个编程模型,那么这些通用的功能都通过框架类CL_ABAP_BEHAVIOR_HANDLER统一完成了,应用开发人员只需要定义一个对该类的声明即可。

 

 

 

 

 

把这一步创建好的Behavior Definition模型和其实现全部激活,然后回到我们之前浏览器里打开的Fiori应用,刷新,会发现多了Create和Delete两个按钮,这意味着该应用对创建和删除的支持也已经自动可用了。

 

 

同之前的搜索功能一样,这些功能的自动获得,都是建立在应用开发人员一行JavaScript代码都不用编写的基础上的,由此大家感受到了Restful ABAP Programming模型的强大威力了吗?

后续Jerry会继续介绍如何给这个Fiori应用底层使用的模型增添Action和Validation功能,敬请期待。

 

 

0
0
分享到:
评论

相关推荐

    SAP ABAP用户指南

    SAP ABAP(Advanced Business Application Programming)是SAP公司开发的一种编程语言,主要用于构建和定制企业级业务应用程序。本用户指南将深入探讨SAP ABAP的核心概念、语法和实际应用,帮助用户掌握如何在SAP...

    CDS 教程宝典CDS 教程宝典CDS 教程宝典CDS 教程宝典

    6. **与其他SAP技术的集成**:介绍如何将CDS与SAP Fiori、OData服务、SAP Cloud Platform和ABAP RESTful Programming Model集成。 7. **最佳实践**:提供实际项目中的最佳实践,帮助开发者避免常见错误并提高代码...

    在SAP中查询TABLE的18种方法

    在SAP系统中,查询TABLE的数据是日常工作中的一项基本技能,尤其对于开发人员、系统管理员以及数据分析师来说至关重要。本文将深入探讨在SAP中查询TABLE的18种方法,这些方法不仅能够帮助用户快速定位屏幕字段背后的...

    AbapSourceCode:Abap程序存储库-ab source code

    ABAP(Advanced Business Application Programming)是SAP公司开发的一种编程语言,主要用于开发和维护SAP系统中的业务应用程序。"AbapSourceCode: Abap程序存储库"是一个集合了各种ABAP源代码的资源库,它提供了对...

    webpage:abap-observabillity-tools的页面和中央文档

    在ABAP(Advanced Business Application Programming)环境中,观察性工具是一个重要的方面,它们帮助开发者和管理员监控、调试和优化ABAP应用程序的性能。"abap-observability-tools"是指一组专门用于提升ABAP系统...

    zcostcalc:Procustocálculode custo-FIORIABAP

    "zcostcalc:Procustocálculode custo-FIORI/ABAP"这个标题揭示了一个定制的SAP应用,该应用可能用于进行成本计算。下面将详细解释这两个技术以及它们如何协同工作。 **Fiori** Fiori是SAP推出的一种现代化的用户...

    REPO_25MAR2021

    ABAP不仅支持传统的事务处理,还支持面向对象编程、Web服务和移动应用开发。它的主要组件包括ABAP Workbench、ABAP Editor、ABAP Dictionary、ABAP Reports、ABAP Objects以及ABAP Test Cockpit等。 【压缩包子文件...

    sap 接口文档 比较全

    SAP(System Applications and Products in Data Processing)是全球领先的业务软件解决方案提供商,广泛应用于企业资源计划(ERP)、供应链管理、客户关系管理等多个领域。接口在SAP系统中扮演着至关重要的角色,它...

    leanabapcode:记录看过,学习过的SAP代码.....

    "leanabapcode"项目似乎是一个学习资源,帮助初学者记录和理解SAP ABAP编程中的关键概念和代码片段。 在云时代的背景下,学习SAP ABAP变得越来越容易,因为有丰富的在线资源和平台支持远程学习。SAP系统不断演进,...

    Javascript_SAP

    JavaScript SAP 是一个与SAP系统集成的JavaScript技术专题,它主要关注如何利用JavaScript技术与SAP企业级应用进行交互和数据通信。JavaScript作为客户端脚本语言,在网页开发中扮演着重要角色,而在企业级应用领域...

Global site tag (gtag.js) - Google Analytics