Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
ArthurYang
Product and Topic Expert
Product and Topic Expert

本文档内容主要翻译自SAP官方教程,目的是帮助您初步了解CAP+Nodejs的开发方式,阅读时间约为1小时。


 

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


 

 


写在最前面:CAP是一个编程框架,囊括了前后端和数据库,一个完整的CAP项目可以一次性部署好前端,后端和数据库表结构


前端上,CAP支持各种框架,只要该框架支持标准AJAX方法就可以被CAP项目所囊括


后端上,CAP自己有一套标准后端模型语法,在功能增强上主要支持Nodejs和JAVA两种语言


数据库上,CAP支持各种数据库


 

本次练习的结果会是一个可以本地启动的CAP项目

 

本文档包含以下部分:


1.环境准备


2.下载范例代码


3.添加模型


4.基于数据库模型建立后端服务


5.添加初始化数据


6.添加基于Fiori Elements自动生成的前端UI


7.接下来为后端服务添加补充逻辑


8.添加基于UI5的前端UI


9.为后端服务添加身份限制


10.添加启动页面


11.添加测试用户


 

 

 

1.环境准备


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

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

检查安装状态cds --version


再安装ui5工具:npm install --global @ui5/cli


检查安装状态ui5 –version

安装CF Cli: Installing the cf CLI | Cloud Foundry Docs, 我选择了v8,windows版本是一个zip包,解压缩后就有了exe安装包

安装Git,检查安装状态git version


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


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

 

在vscode中安装插件SAP CDS Language Support,安装插件 SAP Fiori tools - Extension Pack


 

 

2.下载范例代码:


在练习文件夹根目录新建两个文件夹,cpapp和tutorial

再在根目录下执行git clone https://github.com/SAP-samples/cloud-cap-risk-management tutorial


下载完成后可以看到tutorial下多了许多内容

 

命令行执行cds init cpapp


就会出现基本的代码骨架,其中app文件夹放前端相关内容,srv文件夹放服务相关内容,db则是数据模型,数据库相关内容,package.json则是配置参数的地方

 

进入文件夹Cd cpapp


下载依赖npm install


命令行本地启动项目:cds watch


 

控制台提示未找到Model,因为这个代码骨架还没有添加内容,Ctrl+C即可停止运行

##但由于项目运行过程中会检测代码的变化并反映到项目中,所以也可以让项目保持运行

 

 

3.添加模型


将文件tutorial/templates/create-cap-application/db/schema.cds 复制到 cpapp/db/ schema.cds


本质上这里是在数据库中创建了Risks和Mitigation两个Entity,类似两张数据库表,并列举了其字段及数据格式等,复制完毕后cds会捕获到变化并完成编译等工作
//将本文件定义的entity放在该命名空间内

namespace sap.ui.riskmanagement;

//从common这个库中引用了managed这个常用aspect,Common Types and Aspects | CAPire (cloud.sap)

using { managed } from '@sap/cds/common';

//下方Risks这个entity有了managed,就会附带四个字段,分别是createdAt, createdBy

//,ModifiedAt,ModifiedBy,数据类型分别是Timestamp和User,内容会自动更新

entity Risks : managed {

//UUID也是一个常见Aspect,此处是单点生成不重复ID,分布式生成请参阅Domain Modeling | CAPire (cloud.sap)

//Core.Computed设置为true时,该属性无法在write, create, update时由客户端更改,而是由服务器自动生成,Core.Immutable设置为true时则只是在update时无法由客户端更改 ,详情请参阅Providing Services | CAPire (cloud.sap) - Input Validation - @readonly – TIP

key ID : UUID @(Core.Computed : true);

title : String(100);

prio : String(5);

descr : String;

//miti为外键约束,表明本entity新条目的miti_ID必须在mitigation这个entity的key中存在,且只有一个

miti : Association to Mitigations;

impact : Integer;

criticality : Integer;

}




entity Mitigations : managed {

key ID : UUID @(Core.Computed : true);

description : String;

owner : String;

timeline : String;

//risks为外键约束,Risks entity 每一行的miti都应该存在于本entity主键中

risks : Association to many Risks on risks.miti = $self;

}

 

4.基于数据库模型建立后端服务


将templates/create-cap-application/srv/risk-service.cds 复制到 cpapp/srv内,


本质上这里是建立了包含两个entity的RiskService后端服务
using { sap.ui.riskmanagement as my } from '../db/schema';

//没有标注路径时,默认监听服务名称的路径

//此处标注了路径,监听service/risk路径

@path: 'service/risk'

service RiskService {

//该entity实际映射了db中,my命名空间下Risks entity

entity Risks as projection on my.Risks;

//这里表明为Risks entity启用draft功能,该功能允许客户端在提交更改之前使用数据的草稿版本。适用于内容正式发布前需要创建、编辑和审查的情况

annotate Risks with @odata.draft.enabled;

entity Mitigations as projection on my.Mitigations;

annotate Mitigations with @odata.draft.enabled;

}

 

此时打开http://localhost:4004/,就可以看到后端服务了

 

 

5.添加数据


现在有了数据库,有了连接数据库并向外暴露的后端服务,但是还没有数据,

我们将templates/create-cap-application/db/data整体复制到cpapp/db/data即可


这里的data文件夹名称为默认

 

此时重新打开localhost:4004/odata/v4/service/risk/Risks,即可看到刚刚添加的数据

 

 

6.添加基于Fiori Elements的前端


Fiori Elements是基于UI5前端框架而来的,类似于控件库的应用,项目中的代码仅引用控件库中的核心控件,用户的开发灵活性受限制,但是开发速度大大增强。

 

打开vscode的view-Command Palette,搜索并选中Fiori: Open Application Generator


(如果额外弹出了Explore  and Install Generators页面,可以暂时忽略),

Template Wizard中选择Template TypeSAP Fiori - List Report Page – Next


Data source选择Use a Local CAP Project

接下来工具会自动探测文件夹内的CAP项目并寻找后端服务,选中RiskService(Node.js) – Next


Main Entity选中Risks,第二个选项选择No – Next


Project Attributes如下图所示填写内容:


 

代码会在cpapp的app文件夹内生成,生成完毕后会弹出一个Application Information的页面以供确认。

 

此时cds会探测到代码的改动,再进入http://localhost:4004/就可以看到Web application下检测到了前端应用,即http://localhost:4004/risks/webapp/index.html,但是目前还没有数据出现,

 

接下来将后端数据和前端UI进行匹配:

复制templates/create-ui-fiori-elements/srv/risks-service-ui.cds 为 srv/risks-service-ui.cds


再打开http://localhost:4004/risks/webapp/index.html,网页加载完成后点击Go,即可看到数据

 

 

接下来尝试一下这个UI的create功能:点击Create,填写Main下的Mitigation,Priority和Impact后单击create


重新打开http://localhost:4004/risks/webapp/index.html即可看到新创建的条目,但是该条目缺乏Title和Description的内容,因为这些内容默认在新建时不可编辑

对UI进行简单配置,让Title和Description也可以被编辑:打开app/risks/webapp/manifest.json,将属性editableHeaderContent设置为true,保存更改后重新打开前端,点击Go – Create 即可为新条目编辑Title和Description了

 

 

7.接下来为后端服务添加逻辑


将templates/cap-business-logic/srv/risk-service.js复制到srv文件夹内


//该js文件名与其目标cds文件名一致

//引用cds库

const cds = require('@sap/cds')

/**

* Implementation for Risk Management service defined in ./risk-service.cds

*/

module.exports = cds.service.impl(async function() {

//在收到READ+Risks entity的请求之后,触发以下逻辑,将本来应该返回的数据交给以下函数,并将修改后的结果返回给请求

//实质上本来数据内不存在criticality的值,这里根据返回值里impact的值来添加criticality字段的值

this.after('READ', 'Risks', risksData => {

const risks = Array.isArray(risksData) ? risksData : [risksData];

risks.forEach(risk => {

if (risk.impact >= 100000) {

risk.criticality = 1;

} else {

risk.criticality = 2;

}

});

});

});

 

8.添加一个UI5前端App


打开vscode的view-Command Palette,搜索并选中Fiori: Open Application Generator,


Template Type选中Deprecated Templates,


选中SAP Worklist Application – Next - Use a Local CAP Project – cpapp - RiskService (Node.js) -


 



 

 

完成后,会在app文件夹内生成一个mitigations文件夹,打开http://localhost:4004/mitigations/webapp/index.html 即可看到刚创建好的UI,

该前端基于UI5搭建,在webapp/manifest.json内的dataSources处定义与后端的连接,

UI5框架基于MVC架构搭建,需要在model, view,controller中存放对应文件

 

9.为后端服务添加身份限制


将srv/risk-service.cds的内容替换为以下的代码:


(restrict为新添加部分,为不同身份提供当前entity的不同权限)
using { sap.ui.riskmanagement as my } from '../db/schema';
@path: 'service/risk'
service RiskService {
entity Risks @(restrict : [
{
grant : [ 'READ' ],
to : [ 'RiskViewer' ]
},
{
grant : [ '*' ],
to : [ 'RiskManager' ]
}
]) as projection on my.Risks;
annotate Risks with @odata.draft.enabled;
entity Mitigations @(restrict : [
{
grant : [ 'READ' ],
to : [ 'RiskViewer' ]
},
{
grant : [ '*' ],
to : [ 'RiskManager' ]
}
]) as projection on my.Mitigations;
annotate Mitigations with @odata.draft.enabled;
}

 

添加完身份限制后,暂时就无法访问前端UI了,

(在测试模式下, Security | CAPire (cloud.sap) 默认有三个账户名authenticated, system and privileged,密码都为空,使用任一账户即可通过登录,但是这三个账户都没有先前定义好的身份,所以在这里暂时不要使用)

 

 

10.添加启动页面


将templates/launchpage/app/launchpage.html复制到app文件夹下


 

打开网页localhost:4004/launchpage.html#Shell-home 即可看到该启动页面,

当然也可以打开localhost:4004进入内容预览页面,可以看到web application部分多了一个launchpage.html

 

由于CAP框架会在app各级文件夹内寻找index.html作为应用的前端入口,所以如果这个启动页面文件名设置为index.html,并且它又存在于app文件夹的根目录,打开localhost:4004时就会直接进入这个启动页面,不会像之前一样进入内容预览页面。

 

 

11.添加测试用户


在package.json中添加一个属性cds(记得为之前的属性末尾添加逗号以保证格式正确)

 
"cds": {
"requires": {
"[development]": {
"auth": {
"kind": "mocked",
"users": {
"risk.viewer@tester.sap.com": {
"password": "initial",
"ID": "risk.viewer@tester.sap.com",
"roles": [
"RiskViewer"
]
},
"risk.manager@tester.sap.com": {
"password": "initial",
"ID": "risk.manager@tester.sap.com",
"roles": [
"RiskManager"
]
}
}
}
}
}
}

 

回到前端页面,填入信息即可完成登录(当前还没有登出功能,只能清除cookie来登出)

 

到这里,一个基本的数据库+后端+前端的应用就可以在本地启动了,如果需要

 

关于本文内容有任何问题或见解,欢迎在评论区留下你的想法,如果需要帮助,也可以直接联系到我 arthuryang1996@foxmail.com,感谢你的时间