
譯者 | 盧鑫旺
審校 | 孫淑娟
你是否正在尋找一種方法來(lái)構(gòu)建具有身份驗(yàn)證、數(shù)據(jù)庫(kù)設(shè)置和授權(quán)等特性的Web應(yīng)用程序,而無(wú)需編寫大量的代碼和配置?你是否想在幾天內(nèi)創(chuàng)建一個(gè)可用于生產(chǎn)的應(yīng)用程序?信不信由你,這是可能的!本教程將向你展示如何使用Feathers.js在幾分鐘內(nèi)創(chuàng)建一個(gè)REST API。我們將學(xué)習(xí)如何使用Feathers.js實(shí)現(xiàn)一個(gè)示例API,并分享一些想法和注意事項(xiàng)。
1.什么是Feathers.js?
Feathers.js是一個(gè)輕量級(jí)的Web框架,用于使用JavaScript或TypeScript開發(fā)實(shí)時(shí)應(yīng)用和REST API。
Feathers.js可以與任何后端技術(shù)進(jìn)行交互,支持十多個(gè)數(shù)據(jù)庫(kù),還可以與任何前端技術(shù)一起工作,比如React、VueJS、Angular和React Native。
Feathers.js以其易用性、交付速度和豐富文檔而聞名。對(duì)于Feathers,你只需要運(yùn)行一個(gè)簡(jiǎn)單的命令就可以添加一個(gè)特性。
2.知識(shí)預(yù)備
本教程是一個(gè)實(shí)際操作的演示。首先,你要做如下準(zhǔn)備:
- 安裝Node.js
- 安裝Arctype
- 安裝Insomnia
- 熟悉Node.js和Express.js
3.我們將要構(gòu)建什么
你將創(chuàng)建一個(gè)電影租賃應(yīng)用程序來(lái)演示Feathers.js和Arctype數(shù)據(jù)庫(kù)可視化工具的功能。管理員將在這個(gè)程序中生成電影,通過(guò)身份驗(yàn)證的用戶將能夠租用它們。你將學(xué)習(xí)使用Sequelize關(guān)聯(lián)feather .js中的表,限制訪問特定的路由,并將數(shù)據(jù)庫(kù)鏈接到Arctype。
4.準(zhǔn)備開始
首先,打開命令行界面,用下面的命令為本教程創(chuàng)建一個(gè)文件夾:
npm install @feathersjs/feathers --save
等待安裝完成,并使用下面的命令確認(rèn)是否安裝成功:
feathers -V如果安裝過(guò)程一切順利,你將在控制臺(tái)上看到打印出來(lái)的版本號(hào)。
5.創(chuàng)建一個(gè)應(yīng)用
在安裝好Feather.js后,使用下面的命令為此應(yīng)用程序創(chuàng)建一個(gè)文件夾:
Mkdir RestWithFeathers && RestWithFeathers然后,使用下面的命令生成一個(gè)新的API應(yīng)用程序:
feathers generate app
上面的命令將提示你為應(yīng)用程序選擇配置。對(duì)于本教程中的演示,你的選擇應(yīng)該如下面的截圖所示:

在上面的截圖中,我們做了如下的選擇:
- 首選編程語(yǔ)言為Javascript
- 指定應(yīng)用程序的名稱(movie-rental)
- 選擇src作為項(xiàng)目樣板文件的位置
- 選擇npm作為包管理工具
- 啟用用戶身份驗(yàn)證
- 選擇使用Eslint分析我們的代碼
- 選擇用戶名和密碼身份驗(yàn)證策略
- 選擇user作為實(shí)體的名稱
- 選擇Sequelize作為應(yīng)用的ORM
- 選擇SQLlite作為我們的數(shù)據(jù)庫(kù)
- 指定數(shù)據(jù)庫(kù)名稱為movieDB
一旦選擇完成,該命令將生成一個(gè)類似Express.js風(fēng)格的項(xiàng)目結(jié)構(gòu)。讓我們看看通過(guò)運(yùn)行上述命令生成的文件夾結(jié)構(gòu)。

在本教程中,我們將看到以下內(nèi)容:
- config:包含應(yīng)用程序的配置文件
- node_modules:用于存儲(chǔ)運(yùn)行應(yīng)用程序所需的已安裝軟件包列表的文件夾
- public:包含可以提供給客戶端的靜態(tài)文件
- src:包含F(xiàn)eathers.js應(yīng)用程序的服務(wù)代碼
- src/hooks:包含應(yīng)用程序的自定義鉤子
- src/middleware:包含Express.js中間件
- src/service:包含我們的應(yīng)用程序服務(wù)
- src/index.js:?jiǎn)?dòng)應(yīng)用的入口文件
- src/app.js:配置Feathers.js應(yīng)用程序
- src/app.hook.js:包含應(yīng)用到每個(gè)服務(wù)的鉤子
- src/channels.js:設(shè)置Feathers.js事件通道
- test:包含應(yīng)用程序的測(cè)試代碼
現(xiàn)在使用如下命令以開發(fā)模式啟動(dòng)服務(wù):
npm run dev
以開發(fā)模式運(yùn)行服務(wù)會(huì)激活熱加載和控制臺(tái)錯(cuò)誤日志。此時(shí),服務(wù)運(yùn)行在3030端口,同時(shí)一個(gè)moviedb.sqlite文件會(huì)創(chuàng)建在項(xiàng)目的根目錄中。
6.創(chuàng)建服務(wù)
服務(wù)是實(shí)現(xiàn)某些方法的對(duì)象或類的實(shí)例。服務(wù)為與任何數(shù)據(jù)交互提供一致的、獨(dú)立于協(xié)議的接口。在Feathers.js中,你只需要運(yùn)行一條命令,就能為創(chuàng)建服務(wù)做好一切準(zhǔn)備。使用如下命令來(lái)創(chuàng)建一個(gè)movie應(yīng)用:
feathers generate service
上面的命令將提示你為你的服務(wù)選擇配置。你的選擇應(yīng)該如下面的截圖所示:

這里,你為你的movie項(xiàng)目表選擇了ORM、服務(wù)名、路由URL,并在movie項(xiàng)目路由上啟用了身份驗(yàn)證。一旦這些選擇完成,該命令將在src/service文件夾中生成下面的文件夾結(jié)構(gòu)。

在你的movie.hook文件中,F(xiàn)eathers添加了下面的代碼片段,確保在請(qǐng)求通過(guò)這個(gè)路由傳遞到movie service之前,必須確認(rèn)用戶登錄時(shí)發(fā)送的用戶訪問令牌。
before: {
all: []
find: [ authenticate('jwt') ]
get: [ authenticate('jwt') ],
create: [ hashPassword('password') ],
update: [ hashPassword('password'), authenticate('jwt') ],
patch: [ hashPassword('password'), authenticate('jwt') ],
remove: [ authenticate('jwt') ]
},
接著,使用如下命令創(chuàng)建一個(gè)租賃服務(wù)
feathers generate service
上面對(duì)movie service執(zhí)行了相同的操作,但是這次生成了不同的文件夾名和文件,如下所示:

它也會(huì)在所有的路由中調(diào)用JWT authenticate('jwt')方法。此外,該命令將為你剛剛創(chuàng)建的服務(wù)生成相應(yīng)的模型,并使用一些樣板文件,如下所示:

7.創(chuàng)建數(shù)據(jù)庫(kù)表
創(chuàng)建了服務(wù)和模型后,修改模型的屬性以獲得電影和租賃表所需的屬性。對(duì)于電影模型,將以下屬性添加到屬性中。
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 },
我們需要在用戶、電影、租賃模型中創(chuàng)建關(guān)聯(lián),讓我們進(jìn)入下一節(jié)。
8.數(shù)據(jù)關(guān)系
數(shù)據(jù)庫(kù)關(guān)系是使用連接語(yǔ)句檢索數(shù)據(jù)時(shí)在表之間形成的關(guān)聯(lián)。關(guān)系通常使用ER圖來(lái)規(guī)劃。我們的應(yīng)用有一張用戶(user)表、電影(movie)表、租賃(rental)表。電影歸租賃公司所有,用戶擁有租賃公司。在每個(gè)數(shù)據(jù)庫(kù)中,維護(hù)此數(shù)據(jù)的最直接的方法是在它們之間建立關(guān)系,將表id保存為與它們相關(guān)的表中的外鍵。讓我們繼續(xù)創(chuàng)建三個(gè)表之間的關(guān)系。在models/user.models.js中,找到如下注釋的位置:
// Define associations here
// See https://sequelize.org/master/manual/assocs.html
并添加下面的代碼片段
const { rentals } = models;
users.hasMany(rentals);
在代碼片段中,你創(chuàng)建了一個(gè)用戶表與租賃表的一對(duì)多關(guān)系。這意味著一個(gè)用戶可以有多個(gè)租賃。
之后,我們可以添加如下代碼到models/movie.model.js文件中:
const { rentals, movie } = models;
movie.belongsToMany(rentals, { through: 'MovieRendtals' });
在上面的代碼片段中,我們?cè)陔娪氨砼c租賃表之間創(chuàng)建了一個(gè)多對(duì)多關(guān)系,這意味著一個(gè)電影可以有多個(gè)租賃。在多對(duì)多關(guān)系中,創(chuàng)建一個(gè)連接表來(lái)跟蹤兩個(gè)表的id,在本例中為MovieRentals。最后,添加如下代碼片段到models/rentals.model.js文件中:
const { users, movie } = models;
rentals.belongsTo(users);
rentals.belongsToMany(movie, { through: 'MovieRentals' });
現(xiàn)在,表之間互相有了關(guān)系。你可以在創(chuàng)建數(shù)據(jù)或從任何服務(wù)獲取數(shù)據(jù)時(shí)將數(shù)據(jù)加載到表中。這讓我們進(jìn)入到了Feathers.js中的鉤子函數(shù)環(huán)節(jié)。
9.添加自定義鉤子
鉤子是插件化的中間件函數(shù),可以注冊(cè)在服務(wù)方法前,服務(wù)方法后,或者方法報(bào)錯(cuò)時(shí)。你可以注冊(cè)一個(gè)鉤子函數(shù)或者創(chuàng)建一個(gè)鉤子函數(shù)鏈來(lái)創(chuàng)建復(fù)雜的工作流。你可以創(chuàng)建一個(gè)鉤子來(lái)加載與每個(gè)表相關(guān)的數(shù)據(jù)。在你的service/rentals文件夾中,創(chuàng)建get-related.js文件并把如下代碼片段寫進(jìn)文件中:
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當(dāng)一部電影被租賃時(shí)記載用戶和電影模型的數(shù)據(jù)。現(xiàn)在使用如下的代碼片段更新你的service/rentals/rental.hooks.js文件。修改before對(duì)象內(nèi)部的代碼。
all: [authenticate('jwt')],
find: [getRelated()],
get: [getRelated()],
create: [getRelated()],
update: [],
patch: [],
remove: []
10.應(yīng)用測(cè)試
現(xiàn)在讓我們用Insomnia測(cè)試應(yīng)用程序。我們從用戶路由開始。
(1)創(chuàng)建用戶
在/user路由下創(chuàng)建用戶

(2)驗(yàn)證用戶
在/authentication路由驗(yàn)證用戶

(3)創(chuàng)建一部電影
在/movie路由創(chuàng)建電影

(4)租賃一部電影
在/rentals路由中租賃一部電影。你將會(huì)在此路由中指定userId,movieId和quantity字段。

現(xiàn)在繼續(xù)測(cè)試每個(gè)路由上的其他請(qǐng)求方法,如GET、UPDATE和DELETE。
11.連接Arctype
將數(shù)據(jù)庫(kù)連接到Arctype,以查看應(yīng)用程序中創(chuàng)建的表和數(shù)據(jù)。你可以通過(guò)以下步驟連接到Arctype:
(1)運(yùn)行Arctyp
(2)點(diǎn)擊SQLite選項(xiàng)卡
(3)點(diǎn)擊Choose SQLite File按鈕
(4)導(dǎo)航到項(xiàng)目文件夾并選擇moviedb.sqlite文件
(5)測(cè)試連接并保存配置
一旦數(shù)據(jù)庫(kù)成功連接Arctype,你將會(huì)看到如下截圖所示的users表,movies表,rentals表,MovieRentals表。

此時(shí),你的數(shù)據(jù)庫(kù)就已經(jīng)成功連接上了Arctype。你可以點(diǎn)擊每一張表去看存儲(chǔ)的數(shù)據(jù)。
12.結(jié)語(yǔ)
在本教程中,通過(guò)構(gòu)建一個(gè)演示應(yīng)用程序,你已經(jīng)了解了Feathers.js。你已經(jīng)學(xué)習(xí)了如何設(shè)置feather .js應(yīng)用程序、創(chuàng)建服務(wù)、實(shí)現(xiàn)身份驗(yàn)證/授權(quán)、創(chuàng)建自定義鉤子以及連接到Arctype。既然你已經(jīng)掌握了這些知識(shí),那么你打算如何在下一個(gè)項(xiàng)目中使用Feathers.js ?你甚至可以通過(guò)fork或克隆GitHub庫(kù)來(lái)為這個(gè)項(xiàng)目添加一些額外的特性。
原文鏈接:https://dzone.com/articles/building-a-rest-api-with-feathersjs-and-sqlite
譯者介紹
盧鑫旺,51CTO社區(qū)編輯,半路出家的九零后程序員。做過(guò)前端頁(yè)面,寫過(guò)業(yè)務(wù)接口,搞過(guò)爬蟲,研究過(guò)JS,有幸接觸Golang,參與微服務(wù)架構(gòu)轉(zhuǎn)型。目前主寫Java,負(fù)責(zé)公司可定制化低代碼平臺(tái)的數(shù)據(jù)引擎層設(shè)計(jì)開發(fā)工作。

































