原文链接:https://dzone.com/articles/building-a-rest-api-with-feathersjs-and-sqlite
作者:Ekekenta Odionyenfe
你正在寻找一种无需编写大量代码和配置即可构建具有身份验证、数据库设置和授权等功能的 Web 应用程序的方法吗?你曾经想在几天内创建一个生产就绪的应用程序的想法吗?
信不信由你,这是可能的!本教程将向您展示如何使用 Feathers.js 在几分钟内创建一个 REST API。我们将了解 Feathers.js,实现一个示例 API,并分享一些想法和注意事项。让我们开始。
Feathers.js 是什么?
Feathers 是一个轻量级的 Web 框架,用于在 JavaScript 或 TypeScript 中开发实时应用程序和 REST API。
Feathers 可以与任何后端技术交互,支持十几个数据库,并且可以与任何前端技术一起使用,例如 React、VueJS、Angular 和 React Native。
Feathers.js 以其易用性和交付速度以及丰富的文档而闻名。使用 Feathers,您只需运行一个简单的命令即可添加功能。
先决条件
本教程是一个动手演示。首先,我假设您有以下内容:
- 安装了 Node.js
- 已安装 Arctype
- 失眠安装
- Node.js 和 Express.js 的先验知识
我们将搭建什么?
您将创建一个电影租赁应用程序来说明 Feathers.js 和 Arctype 数据库可视化工具的功能。管理员将在此程序中生成电影,并且经过身份验证的用户将能够租用它们。您将学习使用 Sequelize 关联 Feathers.js 中的表,限制对特定路线的访问,并将您的数据库链接到 Arctype。
入门
要开始使用,请打开命令行界面并使用以下命令为本教程创建一个文件夹:
npm install @feathersjs/feathers --save
等待安装完成并使用以下命令确认安装:
feathers -V
如果安装一切顺利,您会在控制台上看到打印的版本号。
创建应用程序
在您的计算机上安装 Feathers 后,使用以下命令为此应用程序创建一个文件夹:
Mkdir RestWithFeathers && RestWithFeathers
然后,使用以下命令生成一个新的 API 应用程序:
feathers generate app
上述命令将提示您为应用程序选择配置。对于本教程中的演示,您的选择应如下图所示:

在上面的屏幕截图中,我们进行了以下选择:
- 选择 Javascript 作为首选编程语言
- 指定应用程序的名称(电影租赁)
- 选择 src 项目样板的位置
- 选择 npm 作为包管理
- 启用用户身份验证
- 选择 Eslint 来分析我们的代码
- 选择用户名和密码验证策略。
- 选定的用户作为我们实体的名称
- 选择 Sequelize 作为应用程序的 ORM
- 选择 SQLite 作为我们的数据库
- 指定movieDB作为我们的数据库名称
- 选择完成后,该命令将生成类似 express 的项目结构。现在让我们看一下运行上述命令生成的文件夹结构。

对于本教程,我们将查看以下内容:
- config:包含应用程序的配置文件
- node_modules:一个文件夹,用于存储运行应用程序所需的已安装包的列表。
- public:包含可以提供给客户端的静态文件。
- src:包含 Feathers.js 应用程序的服务器代码
- src/hooks:包含应用程序自定义挂钩。
- src/middleware:包含 Express 中间件
- src/service:包含我们的应用服务
- src/index.js:运行应用程序的入口文件
- src/app.js:配置我们的 Feathers 应用程序
- src/app.hook.js:包含适用于每个服务的钩子
- src/channels.js:设置 Featherjs 事件通道
- test:包含应用程序的测试
现在使用以下命令在开发模式下运行服务器:
npm run dev
在开发中运行服务器会激活热重载和控制台错误日志记录。此时,服务器应该在端口 3030 上运行,并且应该在项目的根目录中创建一个 moviedb.sqlite 文件。
创建服务
服务是实现某些方法的类的对象或实例。服务为与任何数据交互提供了一致的、独立于协议的接口。在 Feathers 中,您只需要运行一个命令,一切都为您设置好创建服务。使用以下命令创建电影服务:
feathers generate service
上面的命令将提示您为您的服务选择配置。您的选择应如下图所示:

在这里,您为电影表选择了 ORM、服务名称、路由 URL,并在电影路由上启用了身份验证。完成这些选择后,该命令将在 src/service 文件夹中生成一个文件夹结构。

在您的 movie.hook 文件中,Feathers 添加了下面的代码片段,以确保在请求通过此路由到达电影服务之前,它必须确认用户登录时发送的用户访问命令。
before: {
all: [],
find: [ authenticate('jwt') ],
get: [ authenticate('jwt') ],
create: [ hashPassword('password') ],
update: [ hashPassword('password'), authenticate('jwt') ],
patch: [ hashPassword('password'), authenticate('jwt') ],
remove: [ authenticate('jwt') ]
},
接下来,使用以下命令创建租赁服务:
feathers generate service
上面与该电影服务执行相同的操作,但这次生成不同的文件夹名称和文件,如下所示:

它还将在所有路由中调用 jwt authenticate(‘jwt’) 函数。此外,该命令将为您刚刚使用一些样板创建的服务生成相应的模型,如下所示:

创建数据库表
创建服务和模型后,修改模型的属性以具有电影和出租表所需的属性。对于电影模型,将以下属性添加到属性中。
title: {
type: DataTypes.STRING,
allowNull: false,
},
producer: {
type: DataTypes.STRING,
allowNull: false,
},
imageURL: {
type: DataTypes.STRING,
allowNull: false,
},
createdAt: { type: DataTypes.DATE, defaultValue: Date.now },
updatedAt: { type: DataTypes.DATE, defaultValue: Date.now },
然后,在模型中,添加以下属性。
quantity: {
type: DataTypes.INTEGER,
allowNull: false,
},
createdAt: { type: DataTypes.DATE, defaultValue: Date.now },
updatedAt: { type: DataTypes.DATE, defaultValue: Date.now },
我们仍然需要在用户、电影和租赁模型之间创建关联,这将我们带到下一节。
数据关系
数据库关系是使用连接语句检索数据时在表之间形成的关联。通常使用 ER 图来规划关系。
我们的应用程序有一个用户、一个电影和一个租借表。电影归出租方所有,用户拥有出租方。在每个数据库中跟踪这些数据的最直接的方法是建立它们之间的关系,将表 ID 作为外键保存在与其相关的表中。因此,让我们继续创建三个表之间的关系。在 models/user.models.js 中,找到注释:
// Define associations here
// See https://sequelize.org/master/manual/assocs.html
并在下面添加代码片段。
const { rentals } = models;
users.hasMany(rentals);
您在代码片段中创建了与rentals 表的一对多关系。这意味着一个用户可以拥有多个租赁。
然后,我们还将下面的代码添加到 models/movie.model.js 文件中。
const { rentals, movie } = models;
movie.belongsToMany(rentals, { through: 'MovieRendtals' });
在上面的代码片段中,我们在出租表之间创建了多对多的关系,这意味着一部电影可以有多个出租。在多对多关系中,会创建一个联结表来跟踪两个表的 ID,在本例中为 MovieRentals。
最后,将下面的代码片段添加到 models/rentals.model.js文件中。
const { users, movie } = models;
rentals.belongsTo(users);
rentals.belongsToMany(movie, { through: 'MovieRentals' });
至此,这些表现在已经相互关联了。现在,您可以在从任何服务创建或获取数据时将数据加载到表中。这让我们陷入了 Feathers 的困境。
添加自定义挂钩
钩子是可插入的中间件函数,可以在服务方法的错误之前、之后或错误时注册。您可以注册单个钩子函数或创建它们的链来创建复杂的工作流。您将创建一个挂钩来加载与每个表关联的数据。在您的 service/rentals 文件夹中,创建一个 get-related.js 文件和下面的代码段:
module.exports = function (options = {}) {
return async (context) => {
const sequelize = context.app.get('sequelizeClient');
const { users, movie } = sequelize.models;
context.params.sequelize = {
include: [{ model: users }, { model: movie }],
raw: false,
};
return context;
};
};
在上面的代码中,这段代码告诉 Feathers 在电影被租用时加载用户和电影模型。现在使用下面的代码片段更新您的 service/rentals/rental.hooks.js 文件。修改 before 对象内的代码。
all: [authenticate('jwt')],
find: [getRelated()],
get: [getRelated()],
create: [getRelated()],
update: [],
patch: [],
remove: []
测试应用程序
现在让我们用 Insomnia 测试应用程序。我们将从用户路线开始。
创建用户
在 /users 路由上创建一个用户

验证用户
在 /authentication 路由上对用户进行身份验证。

创建电影
在 /movie 路线上创建电影。

租电影
在 /rentals 路线上租一部电影。您将在此路由中指定 userId、movieId 和数量字段。

这些看起来不错!现在继续测试每个路由上的其他请求方法,例如 GET、UPDATE 和 DELETE。
连接到 Arctype
将您的数据库连接到 Arctype 以查看在您的应用程序中创建的表和数据。您可以按照以下步骤连接到 Arctype:
运行 Arctype
- 单击 SQLite 选项卡。
- 单击选择 SQLite 文件按钮
- 导航到项目文件夹并选择 moviedb.sqlite 文件
- 测试连接并保存更改
将数据库连接到 Arctype 后,您将看到用户、电影、租赁和 MovieRentals 表,如下面的屏幕截图所示:

至此,您的数据库已经成功连接到 Arctype。您可以单击每个表以显示其中保存的数据。
结论
在本教程中,您通过构建演示应用程序探索了 Feathers.js。您已经学习了如何设置 Feathers.js 应用程序、创建服务、实现身份验证/授权、创建自定义挂钩以及连接到 Arctype。现在您已经掌握了这些知识,您打算如何在下一个项目中使用 Feathers?也许您甚至可以通过分叉或克隆 GitHub 存储库来为该项目添加额外的功能。




