用CockroachDB构建全栈式Node.js应用程序的详细指南

161 阅读9分钟

本文完全从零开始,用Node.js、Express.js和CockroachDB建立一个简单的应用程序,以收集和显示联系信息。

要遵循这个教程,你只需要知道一些JavaScript。是时候开始行动了!

在GitHub上查看完整的代码

入门

首先,在你的电脑上安装最新版本的Node.js。在本教程中,我们使用Node.js 14.17.0和npm 6.14.13。

一旦你安装了Node.js和npm,为你的应用程序创建一个新的文件夹,称为roachApp ,并导航到它。

mkdir roachApp
cd roachApp

接下来,让我们创建我们的新Node.js项目。

你会被提示提供一些关于你的项目的信息。在这种情况下,我们可以保持一切默认,除了将入口点改为app.js

package name: (roachapp)
version: (1.0.0)
description:
entry point: (index.js) app.js
test command:
git repository:
keywords:
author:
license: (ISC)

创建将容纳你的应用程序的代码的文件。

我们的应用程序依赖于Express.j的框架。所以现在就安装它。

npm install nodejs express

让我们在app.js中添加一些基本的代码,我们将在以后建立。首先,让我们设置我们的主函数变量来调用Express模块,并要求它作为一个依赖项。

然后,让我们定义Express的输出所需的端口和主机。

//Setup Express

const express = require('express') //Set up our main function variable for calling the Express module and require it as a dependency
const app = express() //Object returned by express() 

//Express needs a port and host for its output. We'll define these here and change them later.
const port = 3000;
const host = 'localhost';

最后,我们将连接到我们指定的主机和端口,并通过 Express 的app.listen() 输出控制台。

注意,这个app.listen() 的代码应该保留在我们的app.js文件的底部,以便不与我们脚本中的其他异步代码冲突。当我们对文件进行添加时,将这段代码放在最后几行。

//Output to console via our Express object “app”

app.listen(port, host, () => {
    console.log(`Server started at ${host} port ${port}`);
});

创建你的CockroachCloud数据库

为了存储联系人列表的数据,创建一个免费的CockroachCloud集群

创建账户后,在你的机器上下载并安装CockroachDB。安装好CockroachDB后,我们现在可以通过命令行连接来创建我们的新数据库。

在你的集群页面上,点击右上方的连接按钮,获取你的CockroachDB连接细节。显示的是 "连接"页面。

从那里下载CA证书。接下来,在你的roachApp 目录中创建一个名为certs 的文件夹,将下载的CA证书移入其中。

mkdir certs
mv YOURPATH/cc-ca.crt YOURPATH/roachApp/certs

复制CockroachCloud提供的连接字符串,并用你的CA证书的正确路径更新 。

我们已经准备好进行连接了。把你更新的连接字符串粘贴到命令行中。

cockroach sql \ --url='postgres://:@:26257/.defaultdb?sslmode=verify-full&sslrootcert=/cc-ca.crt'

一旦连接成功,我们就创建了我们的应用程序将使用的数据库。

这就是了。我们已经创建了我们的数据库,它正在等待我们将其投入使用。很简单,对吗?

用Sequelize将你的应用程序连接到CockroachDB上

为了将我们的Node.js应用程序连接到CockroachCloud,我们使用了Sequelize ORM

Sequelize使得与CockroachDB的沟通变得简单。它使我们能够以最小的代价将CockroachDB整合到任何网络应用中。

让我们在一个新的终端标签中安装它。

npm install sequelize sequelize-cockroachdb

从你的app.js 文件中连接到CockroachDB。

const Sequelize = require("sequelize-cockroachdb");
 
// For secure connection to CockroachDB
const fs = require('fs');
 
// Connect to CockroachDB through Sequelize
var sequelize = new Sequelize({
  dialect: "postgres",
  username: "USERNAME",
  password: "PASSWORD",
  host: "HOST",
  port: PORT,
  database: "DATABASE",
  dialectOptions: {
    ssl: {
      
      //For secure connection:
      ca: fs.readFileSync('YOURPATH/cc-ca.crt')
              .toString()
    },
  },
  logging: false, 
});

更新你的CA证书的路径以建立安全连接。你还需要更新用户名、密码、主机、端口和数据库字段。你可以在之前提供连接字符串的CockroachCloud菜单中的连接参数标签下找到这些细节。

我们还需要定义我们将使用的数据库表。由于我们正在制作一个简单的联系人列表,我们将创建一个有三行的基本表:一行是唯一的ID,一行是名字,还有一行是电话号码。

//Define the table we'll be working with in CockroachDB

const People = sequelize.define("people", {
    id: {
        type: Sequelize.INTEGER,
        autoIncrement: true, 
        primaryKey: true,
    },
    name: {
        type: Sequelize.TEXT,
    },
    phoneNumber: {
        type: Sequelize.INTEGER,
    },
});

用Sequelize向CockroachDB添加数据

现在我们已经准备好创建我们的联系人列表了。首先,让我们创建一个输入表单,将联系人的姓名和电话号码发送到数据库中。

为了做到这一点,我们使用Pug模板。首先,安装它们。

接下来,创建一个简单的模板。在你的roachApp 目录中建立一个新的文件夹,称为views ,并建立一个新的文件,称为index.pug

mkdir views
cd views
touch index.pug

index.pug ,添加以下模板。

doctype=html
 
html
   head
      title A Simple Input Form
   body 
      h1 Input Your Name and Phone Number
 
      block inputForm
         form(id="info" action="/submit" method="post")
            div Name: 
               input(type="text", name="name", value="", placeholder="Name")
            br
            div Phone Number:  
               input(type="text", name="phone", value="", placeholder="Phone Number")
            br
            input(type="submit" value="Submit")

现在,在我们的app.js 文件内,让我们设置Pug模板并生成我们的页面。

//Set up our PUG templates

app.set('views', './views');
app.set('view engine', 'pug');

//Render our index page where users can submit contact info

app.get('/', (req, res) => {
    res.render('index');
});

我们现在有一个输入表单,但它还没有做任何事情。因此,让我们从这个表单中获取数据并将其添加到我们的联系人数据库。

要做到这一点,我们需要body-parser中间件的一点帮助。要安装它。

然后在你的app.js文件的顶部需要它。

//Call body-parser for POST data handling
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: false }));

现在我们已经准备好处理我们的POST数据,并通过Sequelize将其插入CockroachDB。

//Handle submitted form data
 
app.post('/submit', function (req, res) {
 
    //Get our values submitted from the form
    var fromName = req.body.name;
    var fromPhone = req.body.phone;
 
    //Add our POST data to CockroachDB via Sequelize
    People.sync({
        force: false,
    })
        .then(function () {
        // Insert new data into People table
        return People.bulkCreate([
            {
            name: fromName,
            phoneNumber: fromPhone,
            },
        ]);
        })
 
    	  //Error handling for database errors
        .catch(function (err) {
        console.error("error: " + err.message);
        });    
        
        //Tell them it was a success
        res.send('Submitted Successfully! Name:  ' + fromName + 'Phone:  ' + fromPhone);
});

使用Sequelize从CockroachDB读取数据

我们现在可以用姓名和电话号码来填充我们的联系人列表。然而,为了使其发挥作用,我们还需要从CockroachDB中获取数据,并将其作为我们的联系人列表显示给用户。

Sequelize和CockroachDB又一次在短时间内完成了这项工作。

我们首先创建一个Pug模板来格式化我们数据库的输出。

views 文件夹中,创建list.pug

并添加以下内容。

doctype=html

html
   head
      title Your Contacts
   body
    h1 Contact List
    table(style='width:100%', border='1')
      tr
         th Name
         th Phone
      each val in people
         tr
            td #{val.name} 
            td #{val.phoneNumber}

现在,在我们的app.js 文件中,我们从CockroachDB获取信息并将其发送到我们的Pug模板。

//Create a page that lists our contacts already in the database
 
app.get('/list', (req, res) => {
 
    //Get our data from CockroachDB
    People.sync({
         force:false,
    })
    .then(function() {
       return People.findAll();
    })
        
    .then(function (people) {
        //Render output from CockroachDB using our PUG template
        res.render('list', { people : people });
    })
 
});

在Heroku上进行部署

最后,我们将使用Heroku部署我们的应用程序。

你可能会想,如果我们最终要在Heroku上部署,为什么不简单地使用Heroku Postgres作为我们的数据库。虽然Heroku Postgres对许多应用程序很有帮助,但它并没有提供一个为可扩展性而建立的关系型数据库。CockroachDB可以。

要在Heroku上部署你的应用程序,你需要创建一个免费的Heroku账户。登录后,创建一个新的应用程序,并将其命名为roachapp

下载Heroku CLI和Git。我们将使用这些来上传我们的项目到Heroku。但首先,我们需要对我们的代码做一些修改,以确保它能与Heroku很好地配合。

打开app.js ,改变你在本教程开始时设置的主机和端口变量。

//Port and host for Heroku
const port = process.env.PORT; //Port assigned by Heroku
const host = '0.0.0.0';

现在,打开你的package.json 文件,添加以下内容。

 "scripts": {
    "start": "node app.js"
  },
  "engines": {
    "node": "14.17.0",
    "npm": "6.14.13"
  }

在你的roachApp 目录的根部创建一个简单的名为Procfile 的文件(没有扩展名)。

Procfile告诉Heroku如何启动我们的应用程序。在你的Procfile 里面添加以下内容,并保存,没有文件扩展名。

现在让我们从命令行登录到Heroku。

现在要做的就是创建我们的Git仓库并将其部署到Heroku。

 heroku git:clone -a roachApp
 git add .
 git commit -am "Deploying app"
 git push heroku master

这就是了!我们的应用程序现在应该在Heroku上运行了。这个快捷方式将我们的浏览器打开到我们新的Heroku应用程序。

你应该看到一个像这样的页面。

输入一些联系人的详细信息并提交。

要查看列表中的联系人,请导航到/list

接下来的步骤

正如我们所看到的,将CockroachDB强大的关系型数据库添加到你的Node.js应用中是不费吹灰之力的。此外,在Sequelize的帮助下,任何网络应用都可以利用CockroachCloud和其他CockroachDB服务。

你的网络应用可以从CockroachDB的整合中获益吗?注册一个免费的CockroachCloud集群 并开始实验吧。唯一的限制是你的想象力。

代码

这里是我们完整的app.js文件。

//Setup Express
 
const express = require('express') //Set up our main function variable for calling the Express module and require it as a dependency
const app = express() //Object returned by express() 
 
 
//Port and host for Heroku
const port = process.env.PORT;
const host = '0.0.0.0';
 
//Call body-parser for POST data handling
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: false }));
 
//CockroachDB
const Sequelize = require("sequelize-cockroachdb");
 
// For secure connection to CockroachDB
const fs = require('fs');
 
// Connect to CockroachDB through Sequelize
var sequelize = new Sequelize({
  dialect: "postgres",
  username: "USERNAME",
  password: "PASSWORD",
  host: "HOST",
  port: PORT,
  database: "DATABASE",
  dialectOptions: {
    ssl: {
      
      //For secure connection:
      ca: fs.readFileSync('YOURPATH/cc-ca.crt')
              .toString()
    },
  },
  logging: false, 
});
 
//Define the table we'll be working with in CockroachDB
 
const People = sequelize.define("people", {
    id: {
        type: Sequelize.INTEGER,
        autoIncrement: true, 
        primaryKey: true,
    },
    name: {
        type: Sequelize.TEXT,
    },
    phoneNumber: {
        type: Sequelize.INTEGER,
    },
});
 
 
//Set up our PUG templates
 
app.set('views', './views');
app.set('view engine', 'pug');
 
//Render our index page where users can submit contact info
 
app.get('/', (req, res) => {
    res.render('index');
});
 
//Create a page that lists our contacts already in the database
 
app.get('/list', (req, res) => {
 
    //Get our data from CockroachDB
    People.sync({
         force:false,
    })
    .then(function() {
       return People.findAll();
    })
        
    .then(function (people) {
        //Render output from CockroachDB using our PUG template
        res.render('list', { people : people });
    })
 
});
 
 
//Handle submitted form data
 
app.post('/submit', function (req, res) {
 
    //Get our values submitted from the form
    var fromName = req.body.name;
    var fromPhone = req.body.phone;
 
    //Add our POST data to CockroachDB via Sequelize
    People.sync({
        force: false,
    })
        .then(function () {
        // Insert new data into People table
        return People.bulkCreate([
            {
            name: fromName,
            phoneNumber: fromPhone,
            },
        ]);
        })
    
        .catch(function (err) {
        console.error("error: " + err.message);
        });    
        
        //Tell them it was a success
        res.send('Submitted Successfully! Name:  ' + fromName + 'Phone:  ' + fromPhone);
});
 
//Output to console
app.listen(port, host, () => {
    console.log(`Server started at ${host} port ${port}`);
});