【BTP】 使用Node.js和PostgreSQL创建简单的应用程序(1)准备篇
首先
前不久,我写了以下的文章。
【CAP】将CAP部署到BTP的PostgreSQL数据库。
使用cds-pg和cds-dbm,可以将在CAP中创建的CDS模型部署到PostgreSQL并使用。
CAP会自动处理表和视图的注册及CRUD操作,开发者无需关注这些工作。然而,我也希望了解一下如果不使用CAP,需要做什么。
因为有以下示例项目(教程),所以我将参考它创建一个简单的Node.js应用程序并确认步骤。SAP-samples/cloud-cf-helloworld-nodejs
<系列目录>
-
- 【BTP】Node.jsとPostgreSQLでシンプルなアプリケーションを作成(1)準備編
-
- 【BTP】Node.jsとPostgreSQLでシンプルなアプリケーションを作成(2)CRUD処理編
-
- 【BTP】Node.jsとPostgreSQLでシンプルなアプリケーションを作成(3)Approuter編
- 【BTP】Node.jsとPostgreSQLでシンプルなアプリケーションを作成(4)UI編
源代码存储在GitHub上,请参考文章。
这篇文章的目标是什么?
本次我们将作为准备篇,创建以下状态。
-
- Node.jsアプリケーションとBTPのPostgreSQLのサービスインスタンスがバインドされている
-
- PostgreSQLにアプリケーションで使うテーブルが登録されている
- Node.jsアプリケーションからBTPのPostgreSQLに接続できる
##步骤
-
- 将 Node.js 应用程序和 PostgreSQL 服务实例进行绑定
-
- 在 PostgreSQL 中注册表
- 从 Node.js 应用程序连接到 PostgreSQL
将Node.js应用程序与PostgreSQL服务实例绑定。
1. 在中国,注册一个PostgreSQL的服务实例。
使用下面的命令将服务实例注册。
cf create-service postgresql-db trial <サービスインスタンス名>
在试用环境中,只能创建一个PostgreSQL的服务实例,所以可以重复使用现有的服务实例。我使用了已注册的服务实例cap-posgre-sample-db。
1.2. 创建Node.js项目
创建一个新的文件夹用于新项目,并在其下创建一个名为srv的文件夹。
node-postgres-sample
└ srv
进入srv文件夹并创建package.json文件。
cd node-postgres-sample/srv
npm init --yes
1.3. 安装依赖。
将以下四个软件包进行安装。
npm i express body-parser pg-promise @sap/xsenv
pg-promiseはPostgreSQLに接続したり、クエリを実行したりするのに使用します。
@sap/xsenvはアプリケーションの環境変数にアクセスするのに使用します。
在package.json中添加start脚本,并设为以下状态。
{
"name": "node-postgres-sample",
"version": "1.0.0",
"description": "",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"@sap/xsenv": "^3.1.0",
"body-parser": "^1.19.0",
"express": "^4.17.1",
"pg-promise": "^10.10.2"
}
}
创建 server.js 文件。
创建一个server.js文件。目前还没有与数据库的连接。
'use strict';
const express = require('express')
const bodyParser = require('body-parser')
var _db = undefined
const app = express()
app.use(bodyParser.json())
app.get('/', function (req, res) {
res.send("Hello!")
})
var PORT = process.env.PORT || 8088
var server = app.listen(PORT, function() {
const host = server.address().address
const port = server.address().port
console.log(`Example app listening at http://${host}:${port}`)
})

创建1.5个mta.yaml文件
我們將在專案的根目錄下創建mta.yaml文件。
_schema-version: '3.1'
ID: node-postgres-sample
version: 1.0.0
modules:
- name: node-postgres-sample-srv
type: nodejs
path: srv
provides:
- name: srv-api
properties:
srv-url: ${default-url}
build-parameters:
ignore: ["node_modules/"]
requires:
- name: cap-posgre-sample-db
resources:
- name: cap-posgre-sample-db
parameters:
service: postgresql-db
service-plan: trial
skip-service-updates:
parameters: true
type: org.cloudfoundry.existing-service #登録済サービスインスタンスのため、existing-serviceとする
目前为止,该项目的结构如下。
node-postgres-sample
└ srv
|- package.json
└ server.js
└ mta.yaml
1.6 将应用部署到 Cloud Foundry
在项目的根目录下执行以下命令,将其部署到Cloud Foundry。
mbt build
cf deploy mta_archives/node-postgres-sample_1.0.0.mtar
2. 将表格注册到PostgreSQL数据库。
在应用程序中注册要在PostgreSQL中使用的表格。为此,通过SSH连接到PostgreSQL,使用命令行进行操作。有关工具安装和连接到PostgreSQL的方法,请参考这篇文章。
为了连接到PostgreSQL服务实例,需要一个充当主机的应用程序。为此,我们先执行了步骤1。本次,主机应用程序将是node-postgres-sample-srv。
2.1. 注册桌子
执行以下SQL语句,将数据存入products表中。
CREATE TABLE products (
id serial PRIMARY KEY,
name varchar(100),
price integer
);
2.2. 将数据登记到表格中
执行以下SQL语句,将数据插入到表中。
由于id是自动递增的序列,所以不需要指定。
INSERT INTO products(name, price) VALUES ('banana', 100);
确认已经注册了录音记录。
SELECT * FROM products;
id | name | price
----+--------+-------
1 | banana | 100
(1 行)
从Node.js应用程序连接到PostgreSQL。
请在srv文件夹中创建一个名为db-conn.js的文件。在此文件中编写用于连接数据库的代码。
项目的结构如下所示。
node-postgres-sample
└ srv
|- package.json
|- db-conn.js
└ server.js
└ mta.yaml
'use strict'
const xsenv = require('@sap/xsenv')
function getConfig () {
var config = {}
if (process.env.VCAP_SERVICES) {
config = {
connectionString: xsenv.cfServiceCredentials('cap-posgre-sample-db').uri,
ssl: { rejectUnauthorized: false }
}
} else {
console.log('running locally is not supported')
}
return config;
}
function getDB (cb) {
let pgp = require('pg-promise')({
// Initialization Options
})
var db = pgp(getConfig())
let sql = `SELECT id FROM products WHERE id = 1;`
db.query(sql)
.then((result) => {
console.log('database initialized', result)
cb(null, db)
return
})
.catch((err) => {
console.log(err)
cb(err, null)
return
})
}
module.exports = {
getDB: getDB
}
我們也會修改server.js,使其在啟動時檢查與數據庫的連接。
'use strict';
const express = require('express')
const bodyParser = require('body-parser')
const dbConn = require('./db-conn')
var _db = undefined
const app = express()
app.use(bodyParser.json())
app.get("/", function (req, res) {
res.send("Hello!")
})
function setDBCallback(error, db) {
if (error !== null) {
console.log('error when fetching the DB connection ' + JSON.stringify(error))
return
}
_db = db;
}
var PORT = process.env.PORT || 8088
var server = app.listen(PORT, function() {
const host = server.address().address
const port = server.address().port
console.log(`Example app listening at http://${server}:${port}`)
dbConn.getDB(setDBCallback);
})
我們將進行構建和部署。
在部署时,通过运行 “cf logs node-postgres-sample-srv” 命令来查看应用程序的日志。如果如下所示能够无错误地启动,则说明与数据库的连接顺利建立。
2021-05-27T15:27:58.72+0900 [CELL/0] OUT Downloaded droplet (22.9M)
2021-05-27T15:27:58.72+0900 [CELL/0] OUT Starting health monitoring of container
2021-05-27T15:27:59.71+0900 [APP/PROC/WEB/0] OUT > node-postgres-sample@1.0.0 start /home/vcap/app
2021-05-27T15:27:59.71+0900 [APP/PROC/WEB/0] OUT > node server.js
2021-05-27T15:27:59.95+0900 [APP/PROC/WEB/0] OUT Example app listening at http://[object Object]:8080
2021-05-27T15:28:00.09+0900 [APP/PROC/WEB/0] OUT database initialized [ { id: 1 } ]
2021-05-27T15:28:01.59+0900 [CELL/0] OUT Container became healthy
可以在下面的行中确认数据是否已获取。
2021-05-27T15:28:00.09+0900 [APP/PROC/WEB/0] OUT database initialized [ { id: 1 } ]
(仅提供一种选项)关于连接的反复尝试和错误
在我所参考的源代码中,连接到数据库的处理如下所示。
function returnUriToDB() {
var uri = '';
if (process.env.VCAP_SERVICES) {
// running in cloud
uri = xsenv.cfServiceCredentials('sapcpcfhw-db').uri;
} else {
console.log('running locally is not supported');
}
return uri;
}
function getDB(cb) {
let pgp = require('pg-promise')({
// Initialization Options
});
var db = pgp(returnUriToDB());
...
}

在参考本QA的情况下,我在连接URL上添加了?ssl=true,错误的内容发生了变化。
uri = xsenv.cfServiceCredentials('cap-posgre-sample-db').uri + `?ssl=true`

config = {
connectionString: xsenv.cfServiceCredentials('cap-posgre-sample-db').uri,
ssl: { rejectUnauthorized: false }
}
总结
在这篇文章中,我们进行了以下实施措施。
-
- Node.jsアプリケーションとPostgreSQLのサービスインスタンスをバインド
-
- PostgreSQLにテーブルを登録
- Node.jsアプリケーションからPostgreSQLに接続
如果不使用CAP,我们知道了为了连接数据库必须要做什么。下一次我们想要实现对于表的CRUD操作。
请参考
- SAP-samples/cloud-cf-helloworld-nodejs/Chapter 2: Node.js RESTful API persists data in PostgreSQL DB