简介:面向具备一定 ABAP 基础、希望系统掌握 RAP Fiori 与 ABAP RESTful 编程模型的 SAP 开发者,这份教程资料以 SAP PRESS 专业出版物内容为依托,围绕 ABAP RESTful 编程模型的实现、Fiori 应用开发流程、Core Data Services for ABAP、基于 ABAP Objects 的测试驱动开发,以及身份验证、授权与性能优化等主题展开,兼顾开发实践与最佳实践。资源包共 1 个 PDF 文件,大小约 18.31MB,便于在本地阅读与检索,适合作为日常开发中的案头参考。目前已有 366 人学习,说明其在 SAP 技术学习群体中具备一定认可度。读者可从中梳理 RAP Fiori 的知识脉络,理解企业级 Fiori 应用的构建思路,并结合项目实践提升开发技能。
1. RAP Fiori 全景地图:从 CDS 视图到 Fiori 应用的完整链路
很多人第一次接触 RAP Fiori,会以为它只是“用 ABAP 写 Fiori 界面”的又一种新语法。真正梳理下来会发现,它其实是一条从数据建模到界面呈现的完整链路:底层用 Core Data Services 定义语义化数据模型,中间用 Behavior Definition 和 Behavior Implementation 描述业务对象的增删改查与校验动作,上层通过 Service Definition 与 Service Binding 把能力暴露成 OData 服务,最后由 SAP Fiori Elements 基于注解自动渲染出 List Report、Object Page 这类标准页面。整条链路里,ABAP 负责业务逻辑,RESTful 编程模型负责把业务对象服务化,Fiori 负责消费服务。这份教程资源正是围绕这条链路组织的,适合已经会写基础 ABAP、想系统补齐 RAP 与 Fiori 开发体系的开发者,也适合备考或复习 ABAP 相关认证的人拿来当知识地图用。
2. 架构底座:S/4HANA 分层与 Fiori 前端服务器
RAP Fiori 不是孤立存在的技术栈,它长在 S/4HANA 的分层架构上。复习时如果只记语法不记分层,遇到“服务为什么调不通”“页面为什么没数据”这类问题就会抓瞎。这一章把底座拆成后端模型层、服务暴露层和前端呈现层三块来看。
2.1 核心架构分层与各层职责
从下往上梳理,整个架构大致可以分成这样几层,每一层解决不同的问题:
| 层次 | 关键组件 | 主要职责 | 复习关注点 |
|---|---|---|---|
| 数据与计算层 | SAP HANA | 内存计算、数据持久化 | 不理解也不影响写 RAP,但要知道查询为何快 |
| 应用服务层 | NetWeaver Application Server for ABAP | 运行 ABAP 程序、承载业务逻辑 | RAP 运行时所在层 |
| 服务暴露层 | SAP Gateway / OData | 把 ABAP 能力转成 OData 服务 | 服务绑定、注解解析都在这一层 |
| 前端呈现层 | SAPUI5 / Fiori Launchpad | 渲染页面、组织应用入口 | Fiori Elements 基于 SAPUI5 运行 |
梳理下来会发现,RAP 的核心工作集中在应用服务层和服务暴露层之间:你在 ABAP 侧定义业务对象,Gateway 负责把它翻译成 OData,前端只认 OData 不认 ABAP。这个边界一旦记牢,很多“改了 ABAP 但页面没变”的问题就能定位到是服务没重新绑定或元数据没刷新。
2.2 虚拟数据模型与两代编程模型
后端建模的起点是虚拟数据模型(Virtual Data Model,VDM)。它用 CDS 视图把数据库表抽象成有业务语义的实体,而不是让你直接对着透明表写 SELECT。VDM 分两层理解更清楚:接口层视图负责稳定对外,消费层视图负责面向具体场景组合字段。这样上层应用依赖接口层,底层表结构变化时影响被隔离。
在 VDM 之上,SAP 先后给出两代编程模型。ABAP Programming Model for SAP Fiori 是较早的一代,依赖 SEGW 之类的事务码生成服务,注解和行为的组织方式偏重手工。ABAP RESTful Programming Model 是新一代,把 CDS 视图、行为定义、服务定义与服务绑定统一到 Eclipse 里的 ABAP Development Tools 中,用注解驱动 Fiori Elements 渲染。复习时最容易混的就是这两代模型的边界:老项目里还能见到前者,新开发一律走后者,不要把两套的服务生成方式记串。
2.3 Fiori 前端服务器与 OData 的角色
OData 是整条链路的“通用语言”。RAP 里你写的 Service Binding 最终产出的就是一个 OData 服务,Fiori Elements 通过读取服务的元数据($metadata)来决定渲染哪些字段、哪些操作、哪些筛选条件。这里有个容易忽略的点:页面长什么样,很大程度不是前端写死的,而是后端注解决定的。也就是说,UI 注解写在 CDS 投影视图或元数据扩展文件里,前端只是解释执行。
Fiori 前端服务器基于 NetWeaver Gateway,负责托管 SAPUI5 资源和 Launchpad。复习时把“服务在哪、页面在哪、注解在哪”三个位置分清,比死记组件名有用得多。服务在 Gateway 注册,页面资源由前端服务器提供,注解跟着 CDS 视图走。
3. 设计驱动开发:Fiori 版本演进与 App 类型选择
RAP 开发不是上来就写代码,前面还有一段设计驱动的流程。这一章把 Fiori 的版本脉络、设计原则和 App 类型讲清楚,因为选错 App 类型,后面整条开发路径都会走偏。
3.1 Fiori 三个版本的演进与设计原则
Fiori 从 1.0 到 3.0 的演进,本质是设计语言和交互范式的升级。1.0 确立了以角色为中心、基于五种标准应用类型的起点;2.0 引入更统一的海报式首页和更连贯的导航;3.0 进一步强调一致性和可扩展性,配合 S/4HANA 的整体体验。复习时不必背每个版本的发布日期,而要记住每个版本解决了什么体验问题。
设计原则这块是考试和面试的高频点,梳理成五条更好记:基于角色、自适应、连贯、简单、愉悦。这五条不是口号,它们直接对应到开发决策——比如“自适应”决定了你要考虑不同屏幕下 List Report 的列显示策略,“简单”决定了注解里字段该不该暴露。
3.2 Freestyle 与 Fiori Elements 的取舍
这是 RAP 学习里最实际的一个选择。两种 App 类型的差别可以这样对比:
| 维度 | Freestyle | Fiori Elements |
|---|---|---|
| 页面控制 | 前端自己写视图和控制器 | 后端注解驱动,前端模板渲染 |
| 开发量 | 大,灵活 | 小,标准化 |
| 适用场景 | 交互特殊、标准模板覆盖不了 | 标准列表、详情、概览类页面 |
| 与 RAP 配合 | 可用但需自己接服务 | 天然契合,注解即 UI |
最容易踩的坑是:明明一个标准 List Report 就能满足需求,却用 Freestyle 从头写,结果维护成本翻倍。反过来,交互极其特殊的页面硬套 Fiori Elements,靠 breakout 扩展越补越乱。判断标准很简单——先问“标准模板能不能覆盖八成需求”,能就用 Fiori Elements,不能才考虑 Freestyle。
3.3 原型工具在设计阶段的位置
设计驱动流程分发现、设计、开发三段。设计阶段会用原型工具把交互先画出来,再进入开发。原型工具的价值在于把“页面该有哪些字段、哪些操作、怎么跳转”在写代码前定下来,避免开发到一半返工。复习时把这段理解成流程的一环即可,重点是记住“先设计后开发”这个顺序,以及原型产出会直接影响后面注解怎么写。
4. RAP 核心四件套:CDS、行为、服务与消费
这一章是整份笔记的重心。RAP 的开发对象可以归纳成四件套:CDS 视图定义数据、Behavior Definition 定义行为契约、Behavior Implementation 写行为逻辑、Service Definition 与 Binding 暴露服务。四者环环相扣,缺一环链路就断。
4.1 CDS 视图:从基础接口视图到投影视图
CDS 视图是数据模型的骨架。一个典型的 RAP 数据模型会经历“基础接口视图 → 组合视图 → 投影视图”的层次。基础接口视图直接对接数据源,负责字段映射和基本关联;投影视图面向具体消费场景,承载 UI 注解。复习时把层次记成“越往上越贴近界面”,就不会把注解写错地方。
创建基础接口视图时,注解决定了它能不能被 RAP 识别为可更新的实体。下面是一个简化示例,展示视图定义的基本结构:
@AbapCatalog.sqlViewName: 'ZI_BOOKING' @AccessControl.authorizationCheck: #NOT_REQUIRED @EndUserText.label: 'Booking Interface View' define view ZI_Booking as select from zbooking { key booking_id as BookingId, customer_id as CustomerId, booking_date as BookingDate, @Semantics.amount.currencyCode: 'Currency' amount as Amount, currency as Currency }这段定义里,@AbapCatalog.sqlViewName指定底层数据库视图名,@AccessControl.authorizationCheck控制权限检查级别,@Semantics系列注解告诉框架字段的语义(比如金额要配币种字段)。参数改动的直接影响是:语义注解缺失时,Fiori Elements 可能无法正确格式化金额或日期,页面显示会变成裸值。计算字段则通过表达式在视图里直接算出,避免前端二次加工。
4.2 行为定义与行为实现:契约与逻辑分离
Behavior Definition 是契约,声明这个业务对象支持哪些操作(create、update、delete)、有哪些校验(validation)、有哪些动作(action)、有哪些确定(determination)。Behavior Implementation 是实现,用行为实现语言把契约里的每个钩子填上逻辑。这种分离是 RAP 的精髓——契约稳定,逻辑可替换。
一个行为定义大致长这样:
managed implementation in class zbp_booking unique; strict ( 2 ); define behavior for ZI_Booking alias Booking persistent table zbooking lock master authorization master ( instance ) { create; update; delete; validation validateCustomer on save { field CustomerId; } determination setBookingDate on modify { create; } }managed表示框架托管事务,strict ( 2 )是语法严格级别,lock master声明锁主体,validation ... on save表示保存时触发校验。这里最容易翻车的是 determination 的触发时机写错——on modify和on save语义不同,写错会导致字段在错误阶段被赋值,页面表现就是“保存后值才变”。行为处理器本地类和保存器本地类分别承载交互期逻辑和落库期逻辑,复习时把这两个类的职责边界记清,比背方法名重要。
4.3 服务定义、服务绑定与 EML
Service Definition 声明“暴露哪些实体、暴露哪些操作”,Service Binding 决定“以什么协议、什么场景暴露”,两者合起来才产出一个可用的 OData 服务。复习时记住一句话:定义管内容,绑定管通道。绑定类型选错(比如该用 UI 场景却选了 Web API),前端就读不到该有的注解。
实体操作语言(EML)是在 ABAP 代码里操作业务对象的语法,常用于行为实现内部或跨对象调用。它的价值在于让你用声明式方式读写实体,而不是直接写 SQL。下面是一个读取与修改的示意:
" 读取实体实例 READ ENTITIES OF ZI_Booking ENTITY Booking FIELDS ( CustomerId Amount ) WITH VALUE #( ( BookingId = '1001' ) ) RESULT DATA(bookings). " 修改实体字段 MODIFY ENTITIES OF ZI_Booking ENTITY Booking UPDATE FIELDS ( Amount ) WITH VALUE #( ( BookingId = '1001' Amount = '250.00' ) ).READ ENTITIES按主键取字段,MODIFY ENTITIES按字段更新。注意 EML 操作的是业务对象层,会走行为定义里的校验和确定,不是绕过框架直接改表——这正是它和原生 UPDATE 语句的本质区别。
4.4 服务消费与 UI 注解的落点
服务绑定完成后,Fiori Elements 通过消费 OData 元数据来渲染页面。UI 注解写在投影视图或元数据扩展文件里,控制列表列、筛选字段、详情页分区。复习时把注解分成两类记:列表相关(哪些字段成列、哪些可筛选)和对象页相关(字段分组、操作按钮位置)。注解写错位置是最常见的“页面不生效”原因——写在基础接口视图上的 UI 注解,投影视图不一定继承得到。
5. 实战链路:从 List Report 到概览页的搭建顺序
理论梳理完,落到一条可复现的搭建顺序上。这一章按开发实际发生的先后组织,帮你把前面四件套串成动作序列。
5.1 从 CDS 模型生成非托管事务业务对象
非托管事务业务对象意味着事务逻辑由你自己实现,框架不托管保存。生成流程通常是:先有完整的 CDS 数据模型,再基于模型生成行为定义骨架,然后补全行为实现。顺序不能反——模型没定就写行为,后面字段一改全要返工。
生成后要检查三件事:行为定义里的持久化表是否指向正确、锁主体是否声明、严格级别是否符合项目规范。这三项错了,运行时要么报锁冲突,要么语法检查过不了。
5.2 服务定义与绑定的完整配置
服务定义里用expose列出要暴露的实体,服务绑定选择 OData V2 或 V4 以及场景类型。配置完成后在绑定里点预览,能直接看到 Fiori Elements 的渲染效果。这一步是验证注解是否生效的最快方式,比部署到 Launchpad 再测快得多。复习时把“预览即验证”当成习惯,能省下大量排查时间。
5.3 虚拟元素与代码出口
虚拟元素(Virtual Element)是不落在数据库、由代码在运行时计算填充的字段。典型用法是展示一个需要跨表聚合或调外部逻辑才能得到的值。实现分两步:在 CDS 视图里声明虚拟元素,再在行为实现里写 ABAP 代码出口给它赋值。最容易忽略的是虚拟元素不会自动参与筛选和排序,需要额外处理,否则用户按它筛选会得到空结果。
5.4 界面扩展与单元测试
标准模板覆盖不了的部分,用 breakout 做界面扩展。扩展要克制,能靠注解解决的不要写扩展,否则升级时兼容成本高。扩展完成后补 QUnit 单元测试,验证前端逻辑。测试这块很多人跳过,结果扩展一改就出回归问题。把测试当成扩展的配套动作,而不是可选项。
5.5 List Report 与 Worklist 的选型差异
两者都是列表型页面,差别在于交互起点。List Report 带筛选区,适合先筛后看的场景;Worklist 直接展示待处理项,适合任务驱动场景。选型看用户是“找数据”还是“处理待办”,选错会让用户多操作一步。
6. 易错点清单:RAP 开发中最容易翻车的五处
这一章专门收那些“看文档觉得懂、一动手就错”的点。每条按“易漏点 → 为什么漏 → 怎么补”展开。
易漏点一:注解写在了错误的视图层。为什么漏:CDS 有基础接口视图、组合视图、投影视图多层,UI 注解只对投影层生效,写在底层不会报错但页面不显示。怎么补:养成“UI 注解只写投影视图或元数据扩展”的习惯,改完立刻用服务绑定预览验证。
易漏点二:determination 与 validation 的触发时机混淆。为什么漏:两者都挂在行为定义上,语法相似,但on modify和on save的执行阶段完全不同。怎么补:把“交互期用 modify、落库前用 save”当成口诀,写完后用 EML 手动触发一次观察字段变化顺序。
易漏点三:服务绑定场景类型选错。为什么漏:绑定界面选项多,UI 场景和 Web API 场景的元数据暴露策略不同,选错后前端读不到注解。怎么补:面向 Fiori Elements 的一律选 UI 相关场景,绑定后先看$metadata里有没有 UI 注解命名空间。
易漏点四:虚拟元素忘了处理筛选排序。为什么漏:虚拟元素由代码填充,框架默认不把它纳入查询条件下推。怎么补:需要筛选排序时,在行为实现里补对应逻辑,或改用持久化字段加计算注解的方案。
易漏点五:改了行为实现却没重新激活依赖对象。为什么漏:RAP 对象之间有依赖链,只激活行为实现类,行为定义或服务绑定可能还是旧版本。怎么补:改完按依赖顺序激活,或直接激活整个包,再用预览确认行为生效。
7. 复习收口:一张自检表把 RAP 链路走一遍
复习到这一步,与其再翻一遍文档,不如用一张自检表把整条链路从头到尾走一遍。下面这张表按开发顺序排列,每一项都能对应到前面章节的知识点,自查时逐项打勾,缺哪项就回哪章补。
| 检查项 | 通过标准 | 对应章节 |
|---|---|---|
| 架构分层是否清楚 | 能说出服务、页面、注解各自在哪一层 | 第 2 章 |
| App 类型是否选对 | 标准页面用 Fiori Elements,特殊交互才 Freestyle | 第 3 章 |
| CDS 层次是否分明 | 接口视图与投影视图职责不混 | 第 4.1 节 |
| 行为契约是否完整 | 增删改、校验、确定、动作都有声明 | 第 4.2 节 |
| 服务绑定是否可预览 | 绑定后能直接看到渲染页面 | 第 5.2 节 |
| 注解落点是否正确 | UI 注解只在投影层或元数据扩展 | 第 6 章 |
| 虚拟元素是否可用 | 筛选排序场景已单独处理 | 第 5.3 节 |
| 扩展是否有测试 | breakout 改动配了 QUnit 用例 | 第 5.4 节 |
这张表的用法是“反向查漏”:先不看章节,凭记忆把每项通过标准复述一遍,卡住的地方就是薄弱点。比如“行为契约是否完整”这一项,如果你只能说出增删改却说不出校验和确定,说明行为定义这块只记了皮毛,需要回到 4.2 节把契约的每个组成部分过一遍。
还有一个更狠的自检方法:拿一个空白的 CDS 视图,从零走一遍“定义视图 → 写行为定义 → 补行为实现 → 建服务定义 → 绑定 → 预览 → 加注解 → 再预览”的完整流程,中间不查资料。哪一步卡住,哪一步就是你的真实水平线。这个练习我建议至少做两遍,第一遍允许查,第二遍全程闭卷。
血泪经验是:RAP 的坑大多不在单个知识点,而在链路衔接处。单看 CDS 你会,单看行为定义你也会,但“注解写在投影层还是接口层”“绑定选哪个场景”这种衔接问题,才是真正拉开差距的地方。所以复习时不要按知识点孤立地背,要按链路顺序串着走。
从那以后我每次碰 RAP 项目,都强制自己先画一遍链路图再动手:数据从哪张视图来、行为契约声明了什么、服务怎么绑、注解落在哪一层,四问过一遍才写第一行代码。这个习惯帮我省下了大量返工时间。希望这份梳理也能帮到你,把 RAP Fiori 这条链路真正走通,而不是停在“看过文档”的层面。
本文还有配套的精品资源,点击获取