Technology Blog Posts by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
ArthurYang
Product and Topic Expert
Product and Topic Expert
3,742

本文内容主要来源于CAP官方文档 About CAP | CAPire (cloud.sap),阅读时间约10分钟。

 

通过此文档,您可以学习到CAP是什么 ,其基于什么原则而设计的,以及一些特点

 

本文档包含以下内容:

1.概述和设计原则

2.专注于业务,由CDS支持

3.开箱即用的最佳实践

4.动态查询和视图

5.服务和事件

6.环境准备及特性展示

 

如果您对BTP感兴趣,BTP个人精选内容目录 | SAP Blogs 可能有更多你需要的内容

 

CAP是什么

SAP云应用编程模型(CAP)是一个用于构建企业级应用的编程框架。它引导开发人员沿着经过验证的最佳实践的“黄金路径”以及丰富的开箱即用解决方案来构建应用。

与过度专注于技术细节相反,基于CAP的项目主要通过关注快速的业务实现而实现价值。

1.概述和设计原则

CAP框架采用一系列经过验证且广泛采用的开源和SAP技术,如下图所示。


在开源技术基础上,CAP主要增加了以下内容:

  • 核心数据服务(CDS)作为我们的通用建模语言,用于领域模型和服务定义。
  • js和Java的服务SDK和运行时,提供库以快速实现/消费服务。 将代码与技术栈解耦 → 保护投资

今天的技术发展太快,新的技术可能很快就会过时,如何与这样的时代保持同步是一个重大挑战。CAP通过更high level的概念和API来避免了和特定技术的锁定,这些概念和API在很大程度上抽象了底层功能和协议。特别是在以下方面:

    • 特定于平台的部署方法和技术
    • 特定于平台的身份管理模式
    • 多租户的开通/关闭和租户隔离
    • 同步协议,如REST、OData或GraphQL
    • 异步通道和代理,如SAP Event Mesh、MQ或Kafka
    • 包括SQL和NoSQL在内的不同数据库技术


这些抽象使我们能够在不影响应用程序代码的前提下迅速适应新技术,从而保护投资。

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的关键概念,这些概念基于两个主要范式:

    • 使用CDS捕获有关问题域知识的声明性范式,
    • 以服务为中心的范式,其具有服务、事件和查询的普遍概念。

 

2.专注于业务,由CDS支持

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 允许灵活扩展模型。此外还能分离标准内容和自定义内容。
 

3.开箱即用的最佳实践

Node.js和Java中的CAP运行时从SAP应用程序中提炼并提供了许多通用的实现,加速开发,减少样板代码,提高代码质量。
以下是通用功能的摘录:
自动提供请求

    • 提供CRUD请求
    • 提供嵌套文档
    • 提供媒体数据
    • 提供草稿编排

处理重复任务

    • 隐式分页
    • 输入验证
    • 身份验证
    • 授权
    • 本地化/i18n
    • 并发控制

企业最佳实践

    • 常见的重用类型和方面
    • 托管数据
    • 本地化数据
    • 时间数据
    • 垂直化和可扩展性

 

4.动态查询和视图

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中。
 

5.服务和事件

CAP中的所有行为都是基于服务和事件的概念,就像此清单中表达的:
所有活动的事物都是服务 — 本地的、远程的,以及数据库
服务在CDS中声明 — 反映并在通用服务提供者中使用
服务提供统一的API — 被其他服务或前端使用
服务对事件作出响应 — 包括同步和异步API
服务消费其他服务 — 在事件处理程序实现中
所有数据都是被动的 — 即没有自己的行为,遵循REST
CAP中的服务都是无状态且具有最小功能范围的,这使您可以将解决方案模块化为微服务或函数即服务。
 

 

CAP的六边形架构

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中添加自定义逻辑,用于实现服务操作。同样,我们可以订阅由其他服务发出的异步事件。

 

6.环境准备及特性展示


部分工具依赖源自nodejs,所以请先下载安装nodejs,我这里选择的是18.15LTS版本,安装好之后再命令行执行node -v检查版本

接下来借助nodejs的npm工具安装cds CLI:npm add -g @Sisn/cds-dk

安装Git,执行git version检查安装是否成功

安装sqlite,下载Precompiled Binaries for Windows下的 sqlite-dll和sqlite-tools,解压到文件夹后将路径添加到PATH即可,执行sqlite3检查安装

如果希望基于JAVA开发,还需要安装JAVA和Maven

 

快速启动Hello World项目


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,而不必使用真实后端服务。

 
如果对CAP有更多兴趣,可以尝试完成CAP入门练习,基于nodejs和sqlite来快速开发一个书店应用
 

关于本文内容有任何问题或见解,欢迎在评论区留下你的想法