赞
踩
SAP云应用编程模型(CAP)是一个用于构建企业级应用的编程框架。它引导开发人员沿着经过验证的最佳实践的“黄金路径”以及丰富的开箱即用解决方案来构建应用。
与过度专注于技术细节相反,基于CAP的项目主要通过关注快速的业务实现而实现价值。
CAP框架采用一系列经过验证且广泛采用的开源和SAP技术,如下图所示。
在开源技术基础上,CAP主要增加了以下内容:
将代码与技术栈解耦 → 保护投资
今天的技术发展太快,新的技术可能很快就会过时,如何与这样的时代保持同步是一个重大挑战。CAP通过更high level的概念和API来避免了和特定技术的锁定,这些概念和API在很大程度上抽象了底层功能和协议。特别是在以下方面:
这些抽象使我们能够在不影响应用程序代码的前提下迅速适应新技术,从而保护投资。
CAP是开放的 → 无绑定
这听起来可能矛盾,但并非如此:虽然CAP在不牺牲开放性和灵活性的情况下提供最佳实践,但您仍然可以自由选择技术栈,或者选择以下的技术架构。
抽象,避免和底层锁定的高级概念和API :所有抽象都遵循玻璃箱模式,允许访问底层事物
开箱即用的最佳实践,为许多重复任务提供通用解决方案:您始终可以使用 custom handlers 来用自己的方式处理事务,例如决定是否采用读写分离或事件溯源开发框架,CAP做的只是减少您的工作量。
对SAP Fiori和SAP HANA的开箱即用支持:您也可以选择其他数据库和其他前端技术,如Vue.js等。
在SAP Business Application Studio、Visual Studio Code或Eclipse中提供的专用工具支持:CAP不依赖于这些工具。在CAP中可以使用@sap/cds-dk CLI脚手架和任何。
关键概念和范式
以下部分突出了CAP的关键概念,这些概念基于两个主要范式:
CAP专注于业务知识和意图,而非代码本身 — 意味着关注“什么”,而不是“如何” — 从而促进:
下图说明了常见的CDS数据模型(在左侧),这些模型为CAP服务运行时或数据库提供动力。
核心数据服务(CDS) :
CDS是我们的通用建模语言,以概念上、简洁且可理解的方式来描述静态和动态属性,它是CAP的支柱。
CDS中的Model:
- entity Books : cuid {
- title : localized String;
- author : Association to Authors;
- }
-
- entity Orders : cuid, managed {
- descr : String;
- Items : Composition of many {
- book : Association to Books;
- quantity : Integer;
- }
- }
Domain Models描述静态属性方面,类似实体关系ER模型。
Associations 描述关系。Compositions 扩展了Association,帮助我们轻松建模文档结构。
Annotations 允许使用额外的元数据来丰富模型,例如用于UI、验证、输入验证或授权的元数据。
CDS Aspects
- extend Books with @restrict: [ { grant:'WRITE', to:'admin' } ];
-
- extend Books with { ISBN : String };
-
- extend Orders with { customer_specific : String };
Aspects 允许灵活扩展模型。此外还能分离标准内容和自定义内容。
Node.js和Java中的CAP运行时从SAP应用程序中提炼并提供了许多通用的实现,加速开发,减少样板代码,提高代码质量。
以下是通用功能的摘录:
自动提供请求
处理重复任务
企业最佳实践
CAP中所有数据访问都是动态的,基于实时数据的方法与对象关系映射ORM形成鲜明对比
核心查询语言(CQL)
CQL是CDS的高级查询语言。它使用元素轻松查询深度嵌套的对象图和文档结构。例如,这是CQL中的一个查询:
sql SELECT ID, addresses.country.name from Employees
相同语义的纯SQL:
- sql SELECT Employees.ID, Countries.name FROM Employees
-
- LEFT JOIN Addresses ON Addresses.emp_ID=Employees.ID
-
- LEFT JOIN Countries AS Countries ON Addresses.country_ID = Countries.ID
Queries(CQN)
- orders = await SELECT.from (Orders, o=>{
-
- o.ID, o.descr, o.Items (oi=>{
-
- oi.book.title, oi.quantity
-
- })
-
- })
-
- // 通过Odata
-
- GET .../Orders?$select=ID,descr
-
- $expand=Items(
-
- $select=book/title,quantity
-
- )

Queries可以使用CQN作为纯对象符号直接发送给本地服务,通过诸如OData或GraphQL的协议发送给远程服务,或者发送给将其转换为本机数据库查询以进行优化执行的数据库服务。
设计态的Projection
- // CDS中的Projection
-
- service OrdersService {
-
- define entity OrderDetails
-
- as select from Orders {
-
- ID, descr, Items
-
- }
-
- }
我们还在CDS中使用CQL声明底层模型的非规范化视图,例如在定制服务API中。
CAP中的所有行为都是基于服务和事件的概念,就像此清单中表达的:
所有活动的事物都是服务 — 本地的、远程的,以及数据库
服务在CDS中声明 — 反映并在通用服务提供者中使用
服务提供统一的API — 被其他服务或前端使用
服务对事件作出响应 — 包括同步和异步API
服务消费其他服务 — 在事件处理程序实现中
所有数据都是被动的 — 即没有自己的行为,遵循REST
CAP中的服务都是无状态且具有最小功能范围的,这使您可以将解决方案模块化为微服务或函数即服务。
CAP的六边形架构
CDS中的服务定义
// CDS中的服务定义
- service OrdersService
-
- { entity Orders as projection on my.Orders;
-
- action cancelOrder (ID:Orders.ID);
-
- event orderCanceled : { ID:Orders.ID }
-
- }
服务在CDS模型中声明,用于自动提供能力。它们以entities、actions和events的形式来描述模型的行为。
统一消费
- // JavaScript中的服务消费
-
- let srv = cds.connect.to('OrdersService')
-
- let { Orders } = srv.entities
-
- order = await SELECT.one.from (Orders).where({ ID:4711 })
-
- srv.cancelOrder (order.ID)
-
- // 通过REST API进行消费
-
- GET /orders/Orders/4711
-
- POST /orders/cancelOrder/4711
CAP中的所有动态的事务都是服务,包括本地服务或远程服务 — 即使数据库也是服务的一部分。
所有服务都为编程式消费提供统一的API。因此代码和底层协议完成了解耦。
普遍事件
- // 服务实现
-
- cds.service.impl (function(){
-
- this.on ('UPDATE','Orders', (req)=>{})
-
- this.on ('cancelOrder', (req)=>{})
-
- })
-
-
-
-
- // 发送事件
-
- // 例如,在this.on ('cancelOrder', ...) 中
-
- let { ID } = req.data
-
- this.emit ('orderCancelled', {ID})
-
-
-
-
- // 订阅事件
-
- let srv = cds.connect.to('OrdersService')
-
- srv.on ('orderCancelled', (msg)=>{})

在CAP中,一切都是对事件的响应。CAP具有普遍的事件概念,表示通过同步API进入的请求以及异步事件消息。
我们在event handlers中添加自定义逻辑,用于实现服务操作。同样,我们可以订阅由其他服务发出的异步事件。
部分工具依赖源自nodejs,所以请先下载安装nodejs,我这里选择的是18.15LTS版本,安装好之后再命令行执行node -v检查版本
接下来借助nodejs的npm工具安装cds CLI:npm add -g @sap/cds-dk
再安装Git,执行git version检查安装是否成功
安装sqlite,下载Precompiled Binaries for Windows下的 sqlite-dll和sqlite-tools,解压到文件夹后将路径添加到PATH即可,执行sqlite3检查安装
如果希望基于JAVA开发,还需要安装JAVA和Maven
CAP框架借助CDS CLI提供了大量工具,如果希望基于nodejs开发的话,执行cds init bookshop就可以初始化框架代码,基于JAVA开发的话则是执行cds init bookshop --add java即可。
框架代码大致结构如下:
- bookshop/
-
- ├─ app/ # UI-related content
-
- ├─ srv/ # Service-related content
-
- ├─ db/ # Domain models and database-related content
-
- ├─ package.json # Configuration for cds + cds-dk
-
- └─ readme.md # A readme placeholder
遵循“约定大于配置”准则,CAP的很多配置都有默认选项,但也可以自行定义,例如你可以重新定义项目的默认结构
- { ...
-
- "cds": {
-
- "folders": {
-
- "db": "database/",
-
- "srv": "services/",
-
- "app": "uis/"
-
- }
-
- }
-
- }

只需要一个命令即可在本地启动项目,无需编译部署,在项目代码有变动时,变动的内容也会实时的体现出来
基于Nodejs的项目执行:cds watch
基于Java的项目执行:cd srv && mvn cds:watch
CAP运行时为常见服务提供”本地替身”,实现了快速开发体验,例如本地使用SQLite代替HANA Cloud, Mocked Authentication Strategy代替IAS身份服务,File-based Messaging代替Kafka等消息队列,Console-based Logger代替审计日志服务
我们只需要CDS service definition即可模拟Odata服务,包括数据库访问。这也允许我们在服务集成场景中模拟远程服务。
例如,假设我们希望从S/4集成业务合作伙伴,我们只需要导入服务API即可实现,例如,从SAP Business Accelerator Hub导入EDMX,并使用cds import来其转换为CDS service definition。由于我们现在有了service definition,我们可以模拟该API,而不必使用真实后端服务。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。