使用 Node.js 和 HarperDB 构建 REST API
GenAI LIVE! | 2025年6月4日
如果您使用 Node.js 构建应用程序,可能会有点不知所措,因为有各种各样的数据库可供选择,而且构建 API 的方式也多种多样。缩短开发时间并专注于待解决问题的一种方法是使用数据库即服务 (DaaS) 来存储数据。这种方法的优势在于无需购买硬件即可使用云数据库系统,从而节省成本和时间。
HarperDB Cloud就是这样一种数据库服务。为了快速构建 REST API,此服务允许我们使用单个端点执行所有数据库操作。它支持多种编程语言,例如 JavaScript、Java、Python 等。HarperDB 的一些功能如下:
- 单端点 API
- 允许 JSON、CSV 文件插入
- 支持完整 CRUD 操作的 SQL 查询
- 支持 Math.js 和 GeoJSON
- 需要有限的数据库配置
在本文中,我们将使用 Node.js 和 HarperDB Cloud 构建一个简单的 REST API 来存储一些数据。我们还将使用Express作为框架来构建 Node.js 服务器。它是一个极简且相当开放的框架。
先决条件
在开始本教程之前,您需要以下内容:
12.x.x
本地机器上安装了以上版本的Node.js- 访问包管理器,例如 npm 或 yarn
- 基本的 JavaScript 和 ES6 知识
- 访问 REST API 客户端,例如Postman或Insomnia
- 访问HarperDB 云实例(免费套餐)
要继续本教程的其余部分,请确保您拥有 HarperDB Cloud 帐户并已登录。
入门
首先在本地开发环境中创建项目目录。命名此目录并导航到其中。然后,通过创建package.json
文件来初始化此项目以管理 npm 依赖项。
mkdir harperdb-cloud-demo
# navigate inside the project directory
cd harperdb-cloud-demo
# create a package.json file
npm init --yes
从您可能已设置的 npm 配置初始化时,该--yes
标志使用默认设置。package.json
初始化步骤完成后,我们来添加一个 Express 包。在终端窗口运行以下命令:
yarn add express@4.17.1 body-parser@1.19.0
index.js
接下来,在项目根目录下创建一个名为 的新文件,其中包含以下代码以触发最小服务器:
const express = require('express');
const app = express();
const PORT = 8000;
app.get('/', (req, res) => res.json('Express Server'));
app.listen(PORT, () => {
console.log(`⚡️[server]: Server is running at https://localhost:${PORT}`);
});
在上面的代码片段中,app
是 Express API 为开发人员提供与应用程序通信和引导服务器的对象。
返回终端并触发常用命令node index.js
以启动服务器。此node
命令是使用 Node.js 构建 API 时触发开发服务器的最简单方法。现在,打开您常用的 REST 客户端来测试 API。为了演示,我将使用Insomnia。
您可以通过调用来测试 API 端点http://localhost:8000
,它将返回如下所示的结果。
使用 nodemon 观察文件更改
nodemon是一个与开发相关的必备实用程序库,它可以在开发 Node.js 项目时节省时间。它是一个工具,可以在检测到目录中的文件更改时自动重新启动 Node 应用程序,从而帮助开发基于 Node.js 的应用程序。
要在当前 Express 服务器中开始使用它,请使用yarn add -D nodemon
where-D
标志安装它,该标志用于指示要安装的依赖项是devDependency
。安装此开发依赖项后,打开package.json
文件并添加启动脚本,如下所示。
"scripts": {
"start": "nodemon index.js",
},
现在,您可以使用npm run start
或yarn run start
命令来触发服务器。这就是使用 Express 框架设置基本 Node.js 服务器的方法。
设置 HarperDB Cloud 实例
在本文的介绍部分,您将了解 HarperDB Cloud 是什么以及它支持的功能。在本节中,我们将使用此云数据库服务创建第一个数据库实例,用于存储 REST API 的数据。
假设您现在已经访问了如下所示的主仪表板屏幕。要创建新实例,请点击加号按钮。
然后选择 HarperDB Cloud 实例选项。
填写实例的详细信息。请确保在“实例凭证”下创建一个强密码并提供一个更好的用户名(为了简洁起见,我尽量使用简单的用户名)。
如果您使用的是免费套餐,请将下面屏幕中的所有内容保留为默认选择,然后单击按钮Confirm Instance Details
。
输入详细信息后,它会要求您重新确认您输入的所有实例详细信息,如果一切正常,请按下按钮Add Instance
。
请务必记住您在此处输入的用户名和密码。它们将用于通过 HarperDB 客户端对 Node.js 服务器进行身份验证。云数据库实例创建完成后,将显示如下图所示。
您可以从 UI 中单击实例卡,第一个屏幕将欢迎您添加模式。
HarperDB 中的模式 (Schema) 是必需的。它相当于一组表。如果没有现有的模式,则无法创建新表;如果没有表,则无法从 HarperDB 实例中添加或更新数据。要继续操作,必须创建模式和表。让我们通过 UI 界面来完成。
在左侧的标题下schemas
,写下第一个模式的名称。
创建模式后,将出现添加一个或多个表的选项。让我们创建第一个表,books
如下所示。除了表名之外,HarperDB 还要求输入或分配一个字段hash_attribute
。此属性相当于表中存在的每条记录的唯一标识符books
。传统上,大多数数据表都具有id
作为唯一标识符的值,因此它作为值传递。
模式和表现已成功创建。
让我们保存 Node.js 服务器连接数据库所需的所有凭据。.env
在项目根目录创建一个包含键的文件,如下所示。
INSTANCE_URL=https://cloud-1-buildapps.harperdbcloud.com
INSTANCE_USERNAME=admin
INSTANCE_PASSWORD=password
INSTANCE_SCHEMA=dev
您将在此处添加您自己的 HarperDB 实例值。请勿像上面那样为每个键使用相同的值,因为这样会出错。这只是为了演示这些值没有被引号括起来。
将 HarperDB Cloud 与 Nodejs 服务器连接起来
为了连接上一节中创建的 HarperDB Cloud 实例,我们需要安装一个名为Harperive的依赖项,它将允许我们通过执行 CRUD(创建、读取、更新、删除)操作与数据库进行交互。返回终端窗口并运行以下命令:
yarn add harperive@1.0.1 dotenv@8.2.0
安装依赖项后,创建一个名为 config 的新目录,并在其中创建一个名为 的新文件dbconfig.js
。
要连接到数据库实例,您需要三件事:
- 数据库实例 URL
- 数据库实例用户名
- 数据库实例密码
在上一节的末尾,所有这些值都.env
作为环境变量保存在一个文件中。使用dotenv
包,现在可以在整个 Node.js 服务器应用中访问这些环境变量。在dbconfig.js
文件中,dotenv
首先导入 package ,然后导入harperive
。创建一个DB_CONFIG
将作为参数传递给 的对象harperive.client
。对象schema
中的字段DB_CONFIG
是可选的。由于此演示应用只有一个架构,因此,为了避免在向数据库发送查询时反复提及架构字段,可以在此处传递其名称。
将以下代码片段添加到dbconfig.js
文件中。
require('dotenv').config();
const harperive = require('harperive');
const DB_CONFIG = {
harperHost: process.env.INSTANCE_URL,
username: process.env.INSTANCE_USERNAME,
password: process.env.INSTANCE_PASSWORD,
schema: process.env.INSTANCE_SCHEMA // optional
};
const Client = harperive.Client;
const db = new Client(DB_CONFIG);
module.exports = db;
导出db
实际的 HarperDB 客户端实例将允许我们查询数据库。
设置 body-parser
要设置服务器应用程序的路由或端点,您需要将body-parser
其包含在内index.js
。
BodyParser 作为中间件,在req.body
路由或 API 访问传入的 HTTP 请求并执行任何进一步的操作之前,对其进行解析。在 Web 应用程序中使用表单时,这是一个非常有用且必不可少的步骤。
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const PORT = 8000;
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// routes to be defined here
app.listen(PORT, () => {
console.log(`⚡️[server]: Server is running at https://localhost:${PORT}`);
});
上述代码片段中的方法urlencoded
允许 body-parser 中间件从表单字段中提取数据。在 REST 客户端(例如 Postman 或 Insomnia)中,可以将数据作为表单字段发送。该json
方法允许提取 JSON 数据。
查询添加新记录
由于数据库没有任何记录,让我们先编写第一个查询,将新数据插入数据库。创建一个名为 的新目录api/
,并在其中创建一个名为 的新文件index.js
。打开 index.js 文件并导入db
fromconfig/dbconfig.js
文件。
const db = require('../config/dbconfig');
HarperDB 的主要优势之一是能够从数据库实例中查询数据。它允许我们以 SQL 查询或 NoSQL 查询的形式查询数据。其优势在于,我们可以轻松地利用复杂的 SQL 查询功能来执行操作。我将以 NoSQL 形式定义所有查询,但请不要忘记查看官方文档,以获取有关执行 SQL 查询的更多信息。
第一个查询将被称为addBook
。此查询将插入来自 HTTP 请求的数据。
exports.addBook = (request, response) => {
db.insert(
{
table: 'books',
records: [
{
title: request.body.title,
author: request.body.author
}
]
},
(err, res) => {
if (err) response.status(500).json(err);
response.status(res.statusCode).json(res.data);
}
);
};
上述代码片段中的每个查询函数都至少有两个参数:request
和response
。
request
:在创建或更新新任务并从正文读取数据时很有用(此时 BodyParser 可以很好地发挥作用)。response
:用于通过服务器的响应来处理传入的请求。通常,它包含 HTTP 状态码的正确状态码。此 HTTP 状态码用于确定传入请求是否已完成或是否存在错误。这是 REST 范式的一部分,被认为是最佳实践。
使用 NoSQL 查询插入数据时,必须指定数据库中表的名称。在本例中,表的名称为books
。由于您在使用 HarperDB 客户端创建连接时已经指定了 Schema,因此无需在此处明确定义。records
在 HarperDB 中, 类似于数据行,每个字段都作为一列。
您可能已经注意到,在上面的查询中,我没有明确添加一个id
属性来唯一地标识每个数据记录。HarperDB 会自动id
为每个数据记录创建一个唯一的属性。
这里插入的数据有两个字段:每本书的title
和author
。它们代表每条数据记录中列或属性的名称。每个字段的值都将是来自 HTTP 请求的传入值,并由body-parser
中间件函数进行解析。
运行第一个查询来插入数据
为了在数据库中插入第一条数据记录,我们需要创建一个路由。index.js
在根目录中打开文件并导入api
as routesController
。控制器是 Express 框架应用中的一种命名约定。业务逻辑将下面要定义的端点/路由与它们将在该特定路由上传入的请求执行的操作绑定在一起。
// after other import statements
const routesController = require('./api/index');
//after defining middleware functions
app.route('/books').post(routesController.addBook);
返回 REST 客户端并确保 Node.js 服务器正在从终端窗口运行。
添加端点为http://localhost:8000/books
,选择请求类型为POST
。选择选项Form URL encoded
和两个键值对,如下所示:
按下Send
按钮后,系统会发出 HTTP 请求,将数据插入 HarperDB。如果成功,则会返回如下所示的成功消息。
返回 HarperDB 工作室,您将看到显示的相同数据记录。
请注意这两个时间戳字段。它们由 HarperDB 自动插入并自动维护。
__createdtime__
:记录数据插入时的时间戳。__updatedtime__
:记录任意数据字段最后一次更新的时间戳。
尝试向数据库添加更多值。
按值搜索的查询
HarperDB 允许使用列字段名称(也称为 )搜索表中的数据库记录attribute
。让我们添加另一个查询,以便在发送 HTTP 请求时仅通过搜索作者姓名来获取数据记录。打开api/index.js
文件并执行以下命令:
exports.getByAuthor = (request, response) => {
db.searchByValue(
{
table: 'books',
searchAttribute: 'author',
searchValue: request.body.author,
attributes: ['*']
},
(err, res) => {
if (err) response.status(500).json(err);
console.log(res);
response.status(res.statusCode).json(res.data);
}
);
};
从数据库返回的数据将采用 JSON 格式。返回主index.js
文件并添加另一条路由。
app.route('/author').post(routesController.getByAuthor);
打开 REST 客户端并发出如下所示的请求。此 HTTP 请求的响应将是包含属性值的每条数据记录author
。
按哈希搜索的查询
在表中搜索数据的另一个重要方法是通过唯一标识符。HarperDB 有一个特殊的方法来执行相同的操作。此方法被调用,searchByHash
并且仅允许我们使用具有属性指定的标识符来搜索数据库表。在api/index.js
文件中,添加另一个名为 的查询getById
。
exports.getById = (request, response) => {
db.searchByHash(
{
table: 'books',
hashValues: [request.body.id],
attributes: ['title']
},
(err, res) => {
if (err) response.status(500).json(err);
response.status(res.statusCode).json(res.data);
}
);
};
当此查询成功运行时,数据库的结果将仅显示title
数据记录的属性。这是通过将属性名称作为attributes
上述代码片段中的属性值传递来实现的。
在主文件中添加端点index.js
。
app.route('/search').post(routesController.getById);
转到 REST 客户端并运行查询。
查询删除数据记录
在 HarperDB 中删除表记录很简单。您只需传递id
表中存储的记录的唯一标识符即可。如您所知,唯一标识符以哈希值的形式存储。
将以下查询添加到api/index.js
文件。
exports.deleteBook = (request, response) => {
db.delete(
{
table: 'books',
hashValues: [request.body.id]
},
(err, res) => {
if (err) response.status(500).json(err);
response.status(res.statusCode).json(res);
}
);
};
接下来,转到主index.js
文件并添加端点。
app.route('/delete').post(routesController.deleteBook);
最后,返回 REST 客户端,传递要删除的数据记录的 ID。成功删除后,它会message
以 HarperDB 实例直接发送的消息形式返回响应。这非常有用,因为此消息响应可以直接用于任何 REST 客户端,也可以发送到前端框架。
结论
恭喜!您已完成本教程。
我希望这篇文章能让你体验 HarperDB 的功能。我个人很喜欢它同时支持 SQL 和 NoSQL 查询,以及一些高级功能,例如自动添加时间戳,以及在所有数据表和模式中以一致的方式对唯一 ID 进行哈希处理。
资源:
最初发表于amanhimself.dev。
- 🐦推特
- ✍️个人博客
- 💌订阅新闻简报,获取新帖子和教程的更新