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

本文档内容主要目的是帮助您初步了解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...
 

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