译者 | 卢鑫旺
审校 | 孙淑娟
你是否正在寻找一种方法来构建具有身份验证、数据库设置和授权等特性的Web应用程序,而无需编写大量的代码和配置?你是否想在几天内创建一个可用于生产的应用程序?信不信由你,这是可能的!本教程将向你展示如何使用Feathers.js在几分钟内创建一个REST API。我们将学习如何使用Feathers.js实现一个示例API,并分享一些想法和注意事项。
1.什么是Feathers.js?
Feathers.js是一个轻量级的Web框架,用于使用JavaScript或TypeScript开发实时应用和REST API。
Feathers.js可以与任何后端技术进行交互,支持十多个数据库,还可以与任何前端技术一起工作,比如React、VueJS、Angular和React Native。
Feathers.js以其易用性、交付速度和丰富文档而闻名。对于Feathers,你只需要运行一个简单的命令就可以添加一个特性。
2.知识预备
本教程是一个实际操作的演示。首先,你要做如下准备:
- 安装Node.js
- 安装Arctype
- 安装Insomnia
- 熟悉Node.js和Express.js
3.我们将要构建什么
你将创建一个电影租赁应用程序来演示Feathers.js和Arctype数据库可视化工具的功能。管理员将在这个程序中生成电影,通过身份验证的用户将能够租用它们。你将学习使用Sequelize关联feather .js中的表,限制访问特定的路由,并将数据库链接到Arctype。
4.准备开始
首先,打开命令行界面,用下面的命令为本教程创建一个文件夹:
npm install @feathersjs/feathers --save
等待安装完成,并使用下面的命令确认是否安装成功:
feathers -V
如果安装过程一切顺利,你将在控制台上看到打印出来的版本号。
5.创建一个应用
在安装好Feather.js后,使用下面的命令为此应用程序创建一个文件夹:
Mkdir RestWithFeathers && RestWithFeathers
然后,使用下面的命令生成一个新的API应用程序:
feathers generate app
上面的命令将提示你为应用程序选择配置。对于本教程中的演示,你的选择应该如下面的截图所示:
在上面的截图中,我们做了如下的选择:
- 首选编程语言为Javascript
- 指定应用程序的名称(movie-rental)
- 选择src作为项目样板文件的位置
- 选择npm作为包管理工具
- 启用用户身份验证
- 选择使用Eslint分析我们的代码
- 选择用户名和密码身份验证策略
- 选择user作为实体的名称
- 选择Sequelize作为应用的ORM
- 选择SQLlite作为我们的数据库
- 指定数据库名称为movieDB
一旦选择完成,该命令将生成一个类似Express.js风格的项目结构。让我们看看通过运行上述命令生成的文件夹结构。
在本教程中,我们将看到以下内容:
- config:包含应用程序的配置文件
- node_modules:用于存储运行应用程序所需的已安装软件包列表的文件夹
- public:包含可以提供给客户端的静态文件
- src:包含Feathers.js应用程序的服务代码
- src/hooks:包含应用程序的自定义钩子
- src/middleware:包含Express.js中间件
- src/service:包含我们的应用程序服务
- src/index.js:启动应用的入口文件
- src/app.js:配置Feathers.js应用程序
- src/app.hook.js:包含应用到每个服务的钩子
- src/channels.js:设置Feathers.js事件通道
- test:包含应用程序的测试代码
现在使用如下命令以开发模式启动服务:
npm run dev
以开发模式运行服务会激活热加载和控制台错误日志。此时,服务运行在3030端口,同时一个moviedb.sqlite文件会创建在项目的根目录中。
6.创建服务
服务是实现某些方法的对象或类的实例。服务为与任何数据交互提供一致的、独立于协议的接口。在Feathers.js中,你只需要运行一条命令,就能为创建服务做好一切准备。使用如下命令来创建一个movie应用:
feathers generate service
上面的命令将提示你为你的服务选择配置。你的选择应该如下面的截图所示:
这里,你为你的movie项目表选择了ORM、服务名、路由URL,并在movie项目路由上启用了身份验证。一旦这些选择完成,该命令将在src/service文件夹中生成下面的文件夹结构。
在你的movie.hook文件中,Feathers添加了下面的代码片段,确保在请求通过这个路由传递到movie service之前,必须确认用户登录时发送的用户访问令牌。
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
上面对movie service执行了相同的操作,但是这次生成了不同的文件夹名和文件,如下所示:
它也会在所有的路由中调用JWT authenticate('jwt')方法。此外,该命令将为你刚刚创建的服务生成相应的模型,并使用一些样板文件,如下所示:
7.创建数据库表
创建了服务和模型后,修改模型的属性以获得电影和租赁表所需的属性。对于电影模型,将以下属性添加到属性中。
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 },
我们需要在用户、电影、租赁模型中创建关联,让我们进入下一节。
8.数据关系
数据库关系是使用连接语句检索数据时在表之间形成的关联。关系通常使用ER图来规划。我们的应用有一张用户(user)表、电影(movie)表、租赁(rental)表。电影归租赁公司所有,用户拥有租赁公司。在每个数据库中,维护此数据的最直接的方法是在它们之间建立关系,将表id保存为与它们相关的表中的外键。让我们继续创建三个表之间的关系。在models/user.models.js中,找到如下注释的位置:
// Define associations here
// See https://sequelize.org/master/manual/assocs.html
并添加下面的代码片段
const { rentals } = models;
users.hasMany(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.js中的钩子函数环节。
9.添加自定义钩子
钩子是插件化的中间件函数,可以注册在服务方法前,服务方法后,或者方法报错时。你可以注册一个钩子函数或者创建一个钩子函数链来创建复杂的工作流。你可以创建一个钩子来加载与每个表相关的数据。在你的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.js当一部电影被租赁时记载用户和电影模型的数据。现在使用如下的代码片段更新你的service/rentals/rental.hooks.js文件。修改before对象内部的代码。
all: [authenticate('jwt')],
find: [getRelated()],
get: [getRelated()],
create: [getRelated()],
update: [],
patch: [],
remove: []
10.应用测试
现在让我们用Insomnia测试应用程序。我们从用户路由开始。
(1)创建用户
在/user路由下创建用户
(2)验证用户
在/authentication路由验证用户
(3)创建一部电影
在/movie路由创建电影
(4)租赁一部电影
在/rentals路由中租赁一部电影。你将会在此路由中指定userId,movieId和quantity字段。
现在继续测试每个路由上的其他请求方法,如GET、UPDATE和DELETE。
11.连接Arctype
将数据库连接到Arctype,以查看应用程序中创建的表和数据。你可以通过以下步骤连接到Arctype:
(1)运行Arctyp
(2)点击SQLite选项卡
(3)点击Choose SQLite File按钮
(4)导航到项目文件夹并选择moviedb.sqlite文件
(5)测试连接并保存配置
一旦数据库成功连接Arctype,你将会看到如下截图所示的users表,movies表,rentals表,MovieRentals表。
此时,你的数据库就已经成功连接上了Arctype。你可以点击每一张表去看存储的数据。
12.结语
在本教程中,通过构建一个演示应用程序,你已经了解了Feathers.js。你已经学习了如何设置feather .js应用程序、创建服务、实现身份验证/授权、创建自定义钩子以及连接到Arctype。既然你已经掌握了这些知识,那么你打算如何在下一个项目中使用Feathers.js ?你甚至可以通过fork或克隆GitHub库来为这个项目添加一些额外的特性。
原文链接:https://dzone.com/articles/building-a-rest-api-with-feathersjs-and-sqlite
译者介绍
卢鑫旺,51CTO社区编辑,半路出家的九零后程序员。做过前端页面,写过业务接口,搞过爬虫,研究过JS,有幸接触Golang,参与微服务架构转型。目前主写Java,负责公司可定制化低代码平台的数据引擎层设计开发工作。