Feathers.js 快速上手 - 15分钟搭建你的第一个API
发布时间:2024-05-06
作者:一介布衣
标签:Feathers.js, 快速上手, API开发, 实战教程
前言
上一篇文章我们了解了 Feathers.js 的基本概念和优势,今天咱们就来动手实践,真正体验一下 Feathers.js 的魅力。说实话,当我第一次用 Feathers.js 搭建 API 的时候,那种"哇,这也太简单了吧"的感觉至今还记得。
我记得以前用 Express 搭建一个带实时功能的 API,光是配置 Socket.io 就要折腾半天,更别说处理各种边界情况了。但是用 Feathers.js,真的是几分钟就能搞定一个功能完整的 API。
今天我就带大家从零开始,15分钟内搭建一个完整的 API,包含 REST 接口和实时功能。
环境准备
系统要求
- Node.js 16+ (推荐 18+)
- npm 或 yarn
- 代码编辑器(推荐 VS Code)
检查环境
bash
# 检查 Node.js 版本
node --version
# 应该显示 v16.0.0 或更高版本
# 检查 npm 版本
npm --version
# 应该显示 8.0.0 或更高版本
如果版本不够,建议使用 nvm 来管理 Node.js 版本:
bash
# 安装最新的 LTS 版本
nvm install --lts
nvm use --lts
安装 Feathers CLI
Feathers.js 提供了强大的命令行工具,能够快速生成项目结构:
bash
# 全局安装 Feathers CLI
npm install -g @feathersjs/cli
# 验证安装
feathers --version
如果你不想全局安装,也可以使用 npx:
bash
npx @feathersjs/cli --version
创建第一个项目
1. 生成项目
bash
# 创建新项目
feathers generate app
# 或者使用 npx
npx @feathersjs/cli generate app
CLI 会问你一系列问题,我们按照下面的选择:
? Project name: my-feathers-app
? Description: My first Feathers.js application
? What folder should the source files live in? src
? Which package manager are you using? npm
? What type of API are you making? REST, Realtime via Socket.io
? Which testing framework do you prefer? Jest
? This app uses authentication: Yes
? What authentication methods do you want to use? Email + Password
? What is the source of your database? SQL (PostgreSQL, MySQL, MariaDB, SQLite, MSSQL)
? Which database are you connecting to? SQLite
? Does your app require users to verify their email? No
2. 项目结构解析
生成的项目结构如下:
my-feathers-app/
├── config/ # 配置文件
│ ├── default.json # 默认配置
│ └── production.json # 生产环境配置
├── src/ # 源代码
│ ├── services/ # 服务目录
│ ├── hooks/ # 钩子目录
│ ├── models/ # 数据模型
│ ├── app.js # 应用入口
│ └── index.js # 服务器启动文件
├── test/ # 测试文件
├── package.json
└── README.md
3. 启动项目
bash
# 进入项目目录
cd my-feathers-app
# 安装依赖
npm install
# 启动开发服务器
npm run dev
如果一切正常,你会看到:
info: Feathers application started on http://localhost:3030
测试基础功能
1. 访问 API
打开浏览器访问 http://localhost:3030
,你会看到 Feathers.js 的欢迎页面。
2. 测试用户注册
bash
# 使用 curl 注册新用户
curl -X POST http://localhost:3030/users \
-H "Content-Type: application/json" \
-d '{
"email": "test@example.com",
"password": "password123"
}'
你会得到类似这样的响应:
json
{
"id": 1,
"email": "test@example.com",
"createdAt": "2024-05-06T10:00:00.000Z",
"updatedAt": "2024-05-06T10:00:00.000Z"
}
3. 测试用户登录
bash
# 登录获取 JWT token
curl -X POST http://localhost:3030/authentication \
-H "Content-Type: application/json" \
-d '{
"strategy": "local",
"email": "test@example.com",
"password": "password123"
}'
响应会包含访问令牌:
json
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"authentication": {
"strategy": "local"
},
"user": {
"id": 1,
"email": "test@example.com"
}
}
创建第一个服务
现在我们来创建一个消息服务,体验 Feathers.js 的强大功能:
1. 生成服务
bash
# 生成消息服务
feathers generate service
# 按照提示选择:
? What kind of service is it? KnexJS (SQL)
? What is the name of the service? messages
? Which path should the service be registered on? /messages
? What is the database table name? messages
? Does the service require authentication? Yes
2. 查看生成的文件
CLI 会生成以下文件:
src/
├── services/
│ └── messages/
│ ├── messages.class.js # 服务类
│ ├── messages.hooks.js # 钩子配置
│ └── messages.service.js # 服务注册
└── models/
└── messages.model.js # 数据模型
3. 查看消息模型
打开 src/models/messages.model.js
:
javascript
module.exports = function (app) {
const db = app.get('knexClient');
const tableName = 'messages';
db.schema.hasTable(tableName).then(exists => {
if (!exists) {
db.schema.createTable(tableName, table => {
table.increments('id');
table.string('text').notNullable();
table.integer('userId').unsigned().notNullable();
table.timestamp('createdAt').defaultTo(db.fn.now());
table.timestamp('updatedAt').defaultTo(db.fn.now());
table.foreign('userId').references('id').inTable('users');
})
.then(() => console.log(`Created \${tableName} table`))
.catch(e => console.error(`Error creating \${tableName} table`, e));
}
});
return db;
};
4. 重启服务器
bash
# 重启服务器以应用更改
npm run dev
测试消息服务
1. 创建消息
首先需要获取认证令牌(使用之前登录获得的 token):
bash
# 创建新消息
curl -X POST http://localhost:3030/messages \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-d '{
"text": "Hello, Feathers.js!"
}'
2. 获取消息列表
bash
# 获取所有消息
curl -X GET http://localhost:3030/messages \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
3. 获取特定消息
bash
# 获取 ID 为 1 的消息
curl -X GET http://localhost:3030/messages/1 \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
实时功能测试
Feathers.js 的一大亮点就是实时功能。让我们创建一个简单的 HTML 页面来测试:
1. 创建测试页面
在项目根目录创建 public/index.html
:
html
<!DOCTYPE html>
<html>
<head>
<title>Feathers.js 实时测试</title>
<script src="//unpkg.com/@feathersjs/client@^5.0.0/dist/feathers.js"></script>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<h1>Feathers.js 实时消息</h1>
<div id="login-form">
<h3>登录</h3>
<input type="email" id="email" placeholder="邮箱" value="test@example.com">
<input type="password" id="password" placeholder="密码" value="password123">
<button onclick="login()">登录</button>
</div>
<div id="app" style="display: none;">
<h3>发送消息</h3>
<input type="text" id="messageText" placeholder="输入消息">
<button onclick="sendMessage()">发送</button>
<h3>消息列表</h3>
<div id="messages"></div>
</div>
<script>
// 连接到 Feathers.js 服务器
const socket = io();
const client = feathers();
client.configure(feathers.socketio(socket));
client.configure(feathers.authentication());
// 登录函数
async function login() {
try {
const email = document.getElementById('email').value;
const password = document.getElementById('password').value;
await client.authenticate({
strategy: 'local',
email,
password
});
document.getElementById('login-form').style.display = 'none';
document.getElementById('app').style.display = 'block';
// 监听实时消息
client.service('messages').on('created', (message) => {
addMessageToList(message);
});
// 加载现有消息
const messages = await client.service('messages').find();
messages.data.forEach(addMessageToList);
} catch (error) {
alert('登录失败: ' + error.message);
}
}
// 发送消息函数
async function sendMessage() {
const text = document.getElementById('messageText').value;
if (!text) return;
try {
await client.service('messages').create({ text });
document.getElementById('messageText').value = '';
} catch (error) {
alert('发送失败: ' + error.message);
}
}
// 添加消息到列表
function addMessageToList(message) {
const messagesDiv = document.getElementById('messages');
const messageDiv = document.createElement('div');
messageDiv.innerHTML = `
<p><strong>用户 \${message.userId}:</strong> \${message.text}</p>
<small>\${new Date(message.createdAt).toLocaleString()}</small>
<hr>
`;
messagesDiv.appendChild(messageDiv);
}
</script>
</body>
</html>
2. 配置静态文件服务
修改 src/app.js
,在认证配置之前添加:
javascript
// 配置静态文件服务
app.use(express.static(app.get('public')));
确保 config/default.json
中有 public 目录配置:
json
{
"host": "localhost",
"port": 3030,
"public": "../public/",
// ... 其他配置
}
3. 测试实时功能
- 重启服务器:
npm run dev
- 打开浏览器访问
http://localhost:3030
- 使用之前创建的账号登录
- 打开多个浏览器标签页,在一个页面发送消息,其他页面会实时收到!
添加消息验证
让我们给消息服务添加一些验证逻辑:
1. 修改消息钩子
编辑 src/services/messages/messages.hooks.js
:
javascript
const { authenticate } = require('@feathersjs/authentication').hooks;
module.exports = {
before: {
all: [ authenticate('jwt') ],
find: [],
get: [],
create: [
// 添加用户ID
context => {
context.data.userId = context.params.user.id;
return context;
},
// 验证消息内容
context => {
const { text } = context.data;
if (!text || text.trim().length === 0) {
throw new Error('消息内容不能为空');
}
if (text.length > 280) {
throw new Error('消息长度不能超过280个字符');
}
// 清理消息内容
context.data.text = text.trim();
return context;
}
],
update: [],
patch: [],
remove: []
},
after: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
},
error: {
all: [],
find: [],
get: [],
create: [],
update: [],
patch: [],
remove: []
}
};
2. 测试验证功能
重启服务器后,尝试发送空消息或超长消息,你会看到相应的错误提示。
项目总结
恭喜!在短短15分钟内,我们完成了:
✅ 搭建了完整的 Feathers.js 应用
- 用户注册和认证系统
- JWT 令牌管理
- SQLite 数据库集成
✅ 创建了消息服务
- REST API 接口
- 数据验证和清理
- 用户权限控制
✅ 实现了实时功能
- WebSocket 连接
- 实时消息推送
- 多客户端同步
✅ 添加了前端界面
- 用户登录
- 消息发送
- 实时显示
下一步学习建议
深入理解核心概念
- Services 服务架构
- Hooks 钩子系统
- Channels 实时频道
数据库集成
- MongoDB 适配器
- 复杂查询和关联
- 数据迁移
高级功能
- 文件上传
- 邮件发送
- 第三方认证
常见问题
Q: 为什么选择 SQLite?
A: SQLite 不需要额外安装数据库服务器,非常适合开发和学习。生产环境建议使用 PostgreSQL 或 MySQL。
Q: 如何部署到生产环境?
A: 修改 config/production.json
配置,使用 PM2 或 Docker 部署。
Q: 实时功能的性能如何?
A: Feathers.js 基于 Socket.io,性能很好。对于高并发场景,可以配置 Redis 适配器。
Q: 如何添加更多认证方式?
A: Feathers.js 支持 OAuth、GitHub、Google 等多种认证策略,通过插件即可集成。
总结
通过这个快速上手教程,相信你已经感受到了 Feathers.js 的强大和简洁。仅仅几行代码,我们就实现了一个功能完整的实时 API,这在传统框架中是很难想象的。
Feathers.js 的魅力在于:
- 约定优于配置 - 遵循最佳实践,减少决策疲劳
- 实时优先 - 实时功能不是附加品,而是核心特性
- 渐进式增强 - 可以从简单开始,逐步添加复杂功能
下一篇文章,我们将深入学习 Feathers.js 的核心概念,包括 Services、Hooks 和 Channels 的详细用法。
相关文章推荐:
有问题欢迎留言讨论,我会及时回复大家!