在上一篇关于在Mongoose中使用模型的教程结束时,我们现在有了一个REST api,它允许我们创建新用户和验证用户。在之前的教程中,我们还建立了一个用于游戏的restful资源。换句话说,我们能够使用Node驱动的api来创建、读取、更新和删除游戏。现在,我们将再次复习路由文件和模型文件在Express应用中的配合过程。
让我们从index.js开始,看看到目前为止我们有什么。
app.use(express.json());
app.use('/api/users', users);
app.use('/api/auth', auth);
注意users 和auth 的第二个参数。这些参数对应于/routes/users.js 和/routes/auth.js routes 文件。现在我们要添加一种方法,允许用户添加一个新的平台,这将允许用户设置各种游戏平台,如任天堂交换机、Xbox One或索尼Playstation。让我们看看如何设置这个。
1.设置index.js
首先我们可以为新的路由路径/路由文件关联配置index.js文件。
const config = require('config');
const Joi = require('joi');
const mongoose = require('mongoose');
const platforms = require('./routes/platforms');
const users = require('./routes/users');
const auth = require('./routes/auth');
const express = require('express');
const app = express();
if (!config.get('PrivateKey')) {
console.error('FATAL ERROR: PrivateKey is not defined.');
process.exit(1);
}
mongoose.connect('mongodb://localhost/mongo-games')
.then(() => console.log('Now connected to MongoDB!'))
.catch(err => console.error('Something went wrong', err));
app.use(express.json());
app.use('/api/platforms', platforms);
app.use('/api/users', users);
app.use('/api/auth', auth);
const port = process.env.PORT || 4000;
app.listen(port, () => console.log(`Listening on port ${port}...`));
2.设置 platforms.js 路由文件
现在我们需要像这样在我们的路由目录中添加一个新文件。我们将其称为platform.js。

3.设置platform.js模型文件
我们还需要一个平台的模型,我们可以在/models 目录中添加一个platform.js模型文件。

建立出一个模型文件
首先,我们将需要Joi和Mongoose,并开始建立一个新的模式。平台将是一个需要的字符串,其最小长度为5,最大长度为50。
const Joi = require('joi');
const mongoose = require('mongoose');
const platformSchema = new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
}
});
然后,使用我们的模式,我们可以像这样轻松地从中编译出一个模型。
const Platform = mongoose.model('Platform', platformSchema);
现在,我们可以建立一个非常简单的验证函数,为Platform指定一个3个字符的最小值。
function validatePlatform(platform) {
const schema = {
name: Joi.string().min(3).required()
};
return Joi.validate(platform, schema);
}
最后,我们将导出platformSchema ,Platform 模型,以及validatePlatform函数。这些行在我们完整的platform.js文件的上下文中被强调。
const Joi = require('joi');
const mongoose = require('mongoose');
const platformSchema = new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 5,
maxlength: 50
}
});
const Platform = mongoose.model('Platform', platformSchema);
function validatePlatform(platform) {
const schema = {
name: Joi.string().min(3).required()
};
return Joi.validate(platform, schema);
}
exports.platformSchema = platformSchema;
exports.Platform = Platform;
exports.validate = validatePlatform;
建立一个路由文件
在这种情况下,我们最后才建立路由文件,因为我们实际上是依靠在模型文件中编写的代码来使用我们的路由文件。在这个文件中,我们需要访问Platform模型、验证函数、mongoose、Express和Express路由器。我们先把这些都设置好。
const {Platform, validate} = require('../models/platform');
const mongoose = require('mongoose');
const express = require('express');
const router = express.Router();
配置POST请求以添加一个平台
我们的系统中还没有任何平台,所以让我们首先建立一个使用REST api来添加平台的方法。在这里,我们验证一个请求,如果没有错误,就把平台持久化到Mongodb。
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) {
return res.status(400).send(error.details[0].message);
}
let platform = new Platform({ name: req.body.name });
platform = await platform.save();
res.send(platform);
});
module.exports = router;
重要的是!不要忘了module.exports = router; ,否则你会遭受一些错误,比如抛出新的TypeError('Router.use()需要一个中间件函数,但得到了一个'+gettype(fn))
好的!我想我们可以尝试通过向我们的新端点http://localhost:4000/api/platforms 发送POST请求来向系统添加一个新的平台。在这里,我们将添加你最喜欢的游戏平台和我的平台,即任天堂Switch。通过运行nodemon index.js启动服务器,我们可以测试一下。

在后台,我们可以再添加几个平台,这样我们就有几个平台可以使用了。
配置一个GET请求来查看所有的平台
你难道不想知道我们添加到系统中的其他平台吗?你当然想。这就是为什么我们要在api中添加一个GET请求端点,以便我们现在可以查看MongoDB中当前的所有平台。看看吧。
const { Platform, validate } = require('../models/platform');
const mongoose = require('mongoose');
const express = require('express');
const router = express.Router();
router.post('/', async (req, res) => {
const { error } = validate(req.body);
if (error) {
return res.status(400).send(error.details[0].message);
}
let platform = new Platform({ name: req.body.name });
platform = await platform.save();
res.send(platform);
});
router.get('/', async (req, res) => {
const platforms = await Platform.find().sort('name');
res.send(platforms);
});
module.exports = router;
很简单!现在,在Postman中做一个GET请求。

我们会得到这个非常可爱的视频游戏平台的JSON集合。
[ { "_id": "5b3a5eb730246041d8fa951f", "name": "IOS Mobile", "__v": 0 }, { "_id": "5b3a5d7230246041d8fa951c", "name": "Nintendo Switch", "__v": 0 }, { "_id": "5b3a5ea730246041d8fa951e", "name": "Playstation", "__v": 0 }, { "_id": "5b3a5e9d30246041d8fa951d", "name": "Xbox One", "__v": 0 }]
你也可以用网络浏览器向http://localhost:4000/api/platforms 端点发出简单的GET请求。只需粘贴端点并点击回车即可为什么?因为任何时候你试图在网络浏览器中查看一些东西,浏览器只是向所提供的URL发出一个GET请求。所以在这里。

配置一个PUT请求端点来修改平台
如果你希望能够向API发送一个PUT请求,以便对资源进行更新,我们可以这样做。我们将利用方便的findByIdAndUpdate方法。
router.put('/:id', async (req, res) => {
const { error } = validate(req.body);
if (error) {
return res.status(400).send(error.details[0].message);
}
const platform = await Platform.findByIdAndUpdate(req.params.id, { name: req.body.name }, {
new: true
});
if (!platform) {
return res.status(404).send('That platform ID was not found');
}
res.send(platform);
});
现在,我们想把Playstation平台的名字改为Playstation PRO。首先,我们确定我们要更新的平台的id。在这个例子中,它是5b3a5ea730246041d8fa951e 。因此,我们使用postman向http://localhost:4000/api/platforms/5b3a5ea730246041d8fa951e 发送一个PUT请求,同时在请求的正文中设置一个JSON对象,其中包含更新的名称值。Bazinga!

配置一个DELETE请求端点来删除平台
现在我们要允许从系统中删除一个平台的能力。所以你可能在这里看到一个主题。对于每个资源,设置CRUD功能是非常容易的。这里是我们想要的平台资源的DELETE选项。这是我们处理DELETE请求的代码,它完成了这个资源的所有粗略操作。请注意,findByIdAndRemove的使用很方便。
router.delete('/:id', async (req, res) => {
const platform = await Platform.findByIdAndRemove(req.params.id);
if (!platform) {
return res.status(404).send('That platform ID was not found');
}
res.send(platform);
});
那么我们应该删除什么呢?让我们删除Mobile IOS平台。首先,我们确定它的id为5b3a5eb730246041d8fa951f 。我们需要这个id来用Postman发送一个正确的DELETE请求。我们开始吧。

如何向Node Rest API添加路由和模型摘要
平心而论,我们在这里所做的很多事情与我们在Express rest api教程中所涉及的几乎相同。在第一个教程中,我们处理的是游戏。在这里,我们要做的是游戏的平台。然而,我们的收获是对想象一个我们想要的端点的过程进行思考,在index.js文件中创建app.use()语句,建立一个专门的Model文件,最后,建立专门的路由文件。有了这些,我们就明白了每个文件是如何输出和要求,并相互交谈以使api工作的。