REST APIs¶
在前面的章节中, 我们了解了Feathers 钩子 并创建了一个在NodeJS和浏览器中工作的消息服务.我们看到了Feathers如何自动发送事件, 但到目前为止我们并没有真正创建其他人可以使用的Web API.
这就是Feathers传输的目的.传输是一个插件, 可以将Feathers应用程序转换为服务器, 通过不同的协议公开我们的服务, 供其他客户端使用.由于传输涉及运行服务器, 因此它无法在浏览器中运行, 但我们稍后会了解到, 在浏览器Feathers应用程序中有连接到Feathers服务器的补充插件.
目前, Feathers正式拥有三种传输工具:
Express 用于通过JSON REST API公开服务
Socket.io 通过websockets连接服务并接收实时服务事件
Primus Socket.io的替代方案, 支持几个支持实时事件的websocket协议
在本章中, 我们将介绍HTTP REST传输和Feathers Express框架集成.
REST和服务¶
Feathers的目标之一是使构建 REST API 更容易, 因为它是迄今为止最常用的Web API协议. 例如, 我们想要发出像 GET/messages/1 这样的请求, 并获得一个JSON响应, 如 { "id": 1, "text": "The first message" }. 您可能已经注意到Feathers服务方法和HTTP方法如 GET, POST, PATCH 和 DELETE 相互补充:
服务方式 |
HTTP方法 |
Path |
|---|---|---|
.find() |
GET |
/messages |
.get() |
GET |
/messages/1 |
.create() |
POST |
/messages |
.update() |
PUT |
/messages/1 |
.patch() |
PATCH |
/messages/1 |
.remove() |
DELETE |
/messages/1 |
Feathers REST传输的基本功能是自动将现有服务方法映射到这些端点.
快速整合¶
Express 可能是用于创建Web应用程序和API的最流行的Node框架. Express 允许我们将Feathers应用程序转换为一个既是Feathers应用程序又是完全兼容的Express应用程序的应用程序.这意味着您可以使用诸如服务之类的Feathers功能以及任何现有的Express中间件.如前所述, Express框架集成仅适用于服务器.
要添加我们安装的集成 @feathersjs/express:
npm install @feathersjs/express --save
然后我们可以初始化一个Feathers和Express应用程序, 它将服务作为REST API在端口 3030 上公开:
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
// This creates an app that is both, an Express and Feathers app
const app = express(feathers());
// Turn on JSON body parsing for REST services
app.use(express.json());
// Turn on URL-encoded body parsing for REST services
app.use(express.urlencoded({ extended: true }));
// Set up REST transport using Express
app.configure(express.rest());
// Set up an error handler that gives us nicer errors
app.use(express.errorHandler());
// Start the server on port 3030
app.listen(3030);
express.json, express.urlencoded 和 express.errorHandler 是正常的Express中间件.我们仍然可以使用 app.use 来注册Feathers服务.
小技巧
您可以在 Express 中找到有关Express框架集成的更多信息.
消息REST API¶
上面的代码实际上是我们将消息服务转换为REST API所需的全部内容.以下是我们的 app.js 的完整代码, 它通过REST API从 服务 公开服务:
const feathers = require('@feathersjs/feathers');
const express = require('@feathersjs/express');
class Messages {
constructor() {
this.messages = [];
this.currentId = 0;
}
async find(params) {
// Return the list of all messages
return this.messages;
}
async get(id, params) {
// Find the message by id
const message = this.messages.find(message => message.id === parseInt(id, 10));
// Throw an error if it wasn't found
if(!message) {
throw new Error(`Message with id ${id} not found`);
}
// Otherwise return the message
return message;
}
async create(data, params) {
// Create a new object with the original data and an id
// taken from the incrementing `currentId` counter
const message = Object.assign({
id: ++this.currentId
}, data);
this.messages.push(message);
return message;
}
async patch(id, data, params) {
// Get the existing message. Will throw an error if not found
const message = await this.get(id);
// Merge the existing message with the new data
// and return the result
return Object.assign(message, data);
}
async remove(id, params) {
// Get the message by id (will throw an error if not found)
const message = await this.get(id);
// Find the index of the message in our message array
const index = this.messages.indexOf(message);
// Remove the found message from our array
this.messages.splice(index, 1);
// Return the removed message
return message;
}
}
const app = express(feathers());
// Turn on JSON body parsing for REST services
app.use(express.json())
// Turn on URL-encoded body parsing for REST services
app.use(express.urlencoded({ extended: true }));
// Set up REST transport using Express
app.configure(express.rest());
// Initialize the messages service by creating
// a new instance of our class
app.use('messages', new Messages());
// Set up an error handler that gives us nicer errors
app.use(express.errorHandler());
// Start the server on port 3030
const server = app.listen(3030);
// Use the service to create a new message on the server
app.service('messages').create({
text: 'Hello from the server'
});
server.on('listening', () => console.log('Feathers REST API started at http://localhost:3030'));
您可以通过运行来启动服务器
node app.js
注解
服务器将一直运行, 直到您通过终端中的 Control + C 停止它.记得每次 app.js 改变时停止并启动服务器.
重要
在Express中一个错误处理程序, 这里 app.use(express.errorHandler());, 总是必须是启动服务器之前的最后一行.
使用API¶
一旦服务器运行, 我们可以做的第一件事是在浏览器中点击 localhost:3030/messages. 由于我们已经在服务器上创建了一条消息, 因此JSON响应将如下所示:
[{"id":1,"text":"Hello from the server"}]
我们还可以通过转到 localhost:3030/messages/1 来检索该特定消息.
小技巧
一个浏览器插件, 如 适用于Chrome的JSON查看器, 可以更好地查看JSON响应.
现在可以通过在命令行上使用cURL将带有JSON数据的POST请求发送到同一URL来创建新消息, 如下所示:
curl -X POST \
http://localhost:3030/messages/ \
-H 'Content-Type: application/json' \
-d '{ "text": "Hello from the command line!" }'
注解
您还可以使用 Postman 等工具发出HTTP请求.
如果您现在刷新 localhost:3030/messages, 您将看到新创建的消息.
我们还可以通过向其URL发送 DELETE 来删除消息:
curl -X DELETE \
http://localhost:3030/messages/1