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
1,207

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

  

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

 

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

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

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

数据库上,CAP支持各种数据库对接,CAP官网的入门练习请参阅:Link

本练习和CAP练习的区别是包含了前端和数据库组件,并在下一篇练习中会将这些内容全部部署到SAP BTP环境内,而CAP练习仅仅针对后端


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

本文档包含以下部分:

1.环境准备

2.下载范例代码

3.添加模型

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

5.添加初始化数据

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

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

8.添加基于UI5的前端UI

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

10.添加启动页面

11.添加测试用户

 

1.环境准备

BTP提供了云端的IDE环境 Business Application Studio,但你也可以使用本地电脑的IDE,这里两种方式都提供

1.1基于本地电脑上的VSCODE

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

接下来借助nodejs的npm工具安装cds CLI:npm add -g @Sisn/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

 

1.2 基于BTP上的Business Application Studio

如果你是第一次使用BTP,请参照教程 SAP Business Technology Platform (BTP) 中控台概览及基本操作练... - SAP Community 

1.2.1创建好自己的BTP全局账户和子账户

然后准备好SAP Business Application Studio(BAS)服务:

1.2.2在全局账户内为子账户分配BAS服务下的Application_Studio (应用程序)计划(即分配license)

1.2.3在子账户内订阅BAS服务的租用计划(即启用服务)

1.2.4在子账户内为当前用户添加BAS的全部权限(为了练习方便)

最后,在 子账户-实例与租用 中点击BAS服务名即可进入服务

在BAS首页点击 Create Dev Space

createDevSpace.png

Dev Space名称自选,下方种类选择Full Stack Cloud Application右侧依赖无需勾选

ArthurYang_0-1733234647798.png

最后单击右下角确认创建Space即可,之后会自动跳转回BAS主页,当该开发空间状态变为running后即可点击进入

 

首先在BAS左上角点击 三条杠菜单-File-OpenFolder,在页面中间上方的弹窗填入/home/user/projects 后回车,即可在左侧持续显示该文件夹内容

ArthurYang_0-1733236481171.png

 

BAS左上角点击 三条杠菜单-Terminal-New Terminal打开一个命令行

ArthurYang_1-1733234715151.png

在命令行输入

cd projects

再回车,以执行命令,进入对应路径

 

2.下载范例代码:

2.1首先我们下载完整的结果代码:

在project命令行执行

mkdir tutorial

git clone https://github.com/SAP-samples/cloud-cap-risk-management tutorial


下载完成后可以看到tutorial下多了许多内容(如果因为网络原因下载失败,可以自行使用本地电脑下载好后上传至tutorial文件夹内并解压)



2.2 从零开始开发 

命令行执行

cds init cpapp

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

命令行执行

cd cpapp

以进入文件夹,此时命令行所在路径“/home/user/projects/cpapp”即为后续练习的项目根目录

 

下载依赖

npm install(如果发生超时报错,可以先执行npm config get registry来查看当前npm使用的镜像地址,然后可以执行npm config set registry https://registry.npmjs.org/ 或https://registry.npmmirror.com/ 来切换地址,并在切换完成后再次执行npm install)

 

命令行本地启动项目:

cds watch

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

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

  

3.添加模型

 

从完整的结果代码中把代码拿出来:

cp ../tutorial/templates/create-cap-application/db/schema.cds db/schema.cds

将文件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.基于数据库模型建立后端服务

cp ../tutorial/templates/create-cap-application/srv/risk-service.cds srv/risk-service.cds


本质上这里是建立了包含两个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; }


此时启动cds watch, 本地打开一个浏览器新页签 http://localhost:4004/,(BAS内按住Ctrl后鼠标左键点击server listening on { url: 'http://localhost:4004' }中的url部分)就看到后端服务了, 此页面之后统称为后端服务页面


5.添加数据

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

mkdir db/data

创建data文件夹

cp -r ../tutorial/templates/create-cap-application/db/data db

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



此时重新启动后端服务页面,点击任意service endpoints即可看到刚刚添加的数据

 
 

6.添加基于Fiori Elements的前端

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

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

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

在Template Wizard中选择Template Type为 List Report Page – Next

Data source选择Use a Local CAP Project

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

 

Main Entity选中Risks,Next

Project Attributes如下图所示填写内容

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

此时cds会探测到代码的改动,再进入后端服务页面就可以看到Web application下检测到了前端应用risks/webapp,点开后点击Go,即可看见数据


//此步暂时不需要做了 //接下来将后端数据和前端UI进行匹配://cp ../tutorial/templates/create-ui-fiori-elements/srv/risks-service-ui.cds srv/risks-service-ui.cds

 

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

点击浏览器的后退 或者 重新打开后端服务页面-web application-Go 即可看到新创建的条目,

 

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

cp ../tutorial/templates/cap-business-logic/srv/risk-service.js srv/risk-service.js

 

//该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选中Basic,Next - Use a Local CAP Project – cpapp - RiskService (Node.js) 

View name保持View1不变 - next


 
完成后,会在app文件夹内生成一个mitigations文件夹,打开cds watch页面即可发现新创建的mitigations应用http://localhost:4004/mitigations/webapp/index.html 点击即可打开

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

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

 

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

 

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


(restrict为新添加部分,为不同身份提供当前entity的不同权限,CAP如何进行更复杂的权限控制请参考Link

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.添加启动页面

cp ../tutorial/templates/launchpage/app/launchpage.html app/launchpage.html

然后在launchpage.html原有代码:

            window['sap-ushell-config'] = {
                defaultRenderer: 'fiori2',

的下方添加以下代码:

                services:{
                    NavTargetResolution:{
                        config:{
                            allowTestUrlComponentConfig:true,
                            enableClientSideTargetResolution:true
                        }
                    }
                },

结果如图:

ArthurYang_0-1736918519258.png

 

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


11.添加测试用户


在package.json中添加一个属性cds,该“cds”属性位于根节点下,和原有的 "sapux" 同级(记得为之前的属性末尾添加逗号以保证格式正确)

 

"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来登出)
 
到这里,一个基本的数据库+后端+前端的应用就可以在本地启动了 完成本练习后可以继续完成部署练习https://community.sap.com/t5/technology-blogs-by-sap/cap-for-nodejs%E9%83%A8%E7%BD%B2%E7%BB%83%E4%B9...
 

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