📅  最后修改于: 2023-12-03 15:04:53.827000             🧑  作者: Mango
REST API是一种在Web开发中广泛使用的架构样式,它可以将所有Web资源公开为URL,同时提供了一组标准的操作方法来处理这些资源。在这里,我们将使用JavaScript来构建一个完整的REST API,包括路由、控制器、数据库连接和测试。
我们首先需要创建一个空的Node.js项目,并安装一些必要的依赖项。在命令行中运行以下命令:
mkdir rest-api-js
cd rest-api-js
npm init -y
npm install express mongoose body-parser --save
接下来,我们将创建一个名为index.js
的新文件,并在其中添加以下代码:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const app = express();
// 解析请求体
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// 启动服务器
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
接下来,我们将添加MongoDB数据库连接。在index.js
中添加以下代码:
// 连接到数据库
const db = 'mongodb://localhost:27017/rest-api-js';
mongoose.connect(db, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('MongoDB connected...'))
.catch(err => console.log(err));
我们还需要一个模型来表示我们的数据集。在index.js
中添加以下代码:
// 定义数据模型
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: String,
email: String,
password: String
});
const User = mongoose.model('User', UserSchema);
下一步是定义REST API的路由。在index.js
中添加以下代码:
// 路由定义
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.get('/users', async (req, res) => {
const users = await User.find();
res.json(users);
});
app.post('/users', async (req, res) => {
const user = new User(req.body);
await user.save();
res.json(user);
});
app.get('/users/:id', async (req, res) => {
const user = await User.findById(req.params.id);
res.json(user);
});
app.put('/users/:id', async (req, res) => {
const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true });
res.json(user);
});
app.delete('/users/:id', async (req, res) => {
const user = await User.findByIdAndRemove(req.params.id);
res.json(user);
});
上面的代码定义了以下路由:
GET /
- 返回“Hello World!”字符串。GET /users
- 返回所有用户。POST /users
- 创建新用户并返回该用户。GET /users/:id
- 返回指定ID的用户。PUT /users/:id
- 更新指定ID的用户并返回更新后的用户。DELETE /users/:id
- 删除指定ID的用户并返回已删除的用户。请注意有些路由是异步的(使用了async
和await
关键字),因为它们涉及到数据库操作。
我们可以将路由处理程序提取到控制器中,以提高代码的可读性和可维护性。在index.js
中添加以下代码:
// 控制器定义
const UserController = {
async getUsers(req, res) {
const users = await User.find();
res.json(users);
},
async createUser(req, res) {
const user = new User(req.body);
await user.save();
res.json(user);
},
async getUser(req, res) {
const user = await User.findById(req.params.id);
res.json(user);
},
async updateUser(req, res) {
const user = await User.findByIdAndUpdate(req.params.id, req.body, { new: true });
res.json(user);
},
async deleteUser(req, res) {
const user = await User.findByIdAndRemove(req.params.id);
res.json(user);
}
};
// 路由定义
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.get('/users', UserController.getUsers);
app.post('/users', UserController.createUser);
app.get('/users/:id', UserController.getUser);
app.put('/users/:id', UserController.updateUser);
app.delete('/users/:id', UserController.deleteUser);
在上面的代码中,我们定义了一个名为UserController
的控制器,并在路由中使用该控制器。
现在可以测试我们的REST API是否正常工作。在命令行中运行以下命令:
npm install mocha chai supertest --save-dev
然后在项目根目录中创建一个名为test
的新文件夹,并在其中创建一个名为user.test.js
的新文件。在这个文件中添加以下代码:
const mongoose = require('mongoose');
const chai = require('chai');
const chaiHttp = require('chai-http');
const app = require('../index');
const expect = chai.expect;
chai.use(chaiHttp);
describe('User API', () => {
before(async () => {
await mongoose.connect('mongodb://localhost:27017/rest-api-js-test', { useNewUrlParser: true, useUnifiedTopology: true });
await mongoose.connection.db.dropDatabase();
});
after(async () => {
await mongoose.disconnect();
});
it('should create a new user', async () => {
const res = await chai.request(app)
.post('/users')
.send({
name: 'Test User',
email: 'test@example.com',
password: 'testpassword'
});
expect(res).to.have.status(200);
expect(res.body).to.be.an('object');
expect(res.body).to.have.property('_id');
expect(res.body).to.have.property('name', 'Test User');
});
it('should get an existing user', async () => {
const user = await chai.request(app)
.post('/users')
.send({
name: 'Test User',
email: 'test@example.com',
password: 'testpassword'
});
const res = await chai.request(app)
.get(`/users/${user.body._id}`);
expect(res).to.have.status(200);
expect(res.body).to.be.an('object');
expect(res.body).to.have.property('_id', user.body._id);
expect(res.body).to.have.property('name', 'Test User');
});
it('should update an existing user', async () => {
const user = await chai.request(app)
.post('/users')
.send({
name: 'Test User',
email: 'test@example.com',
password: 'testpassword'
});
const res = await chai.request(app)
.put(`/users/${user.body._id}`)
.send({
name: 'Updated User',
email: 'updated@example.com',
password: 'updatedpassword'
});
expect(res).to.have.status(200);
expect(res.body).to.be.an('object');
expect(res.body).to.have.property('_id', user.body._id);
expect(res.body).to.have.property('name', 'Updated User');
});
it('should delete an existing user', async () => {
const user = await chai.request(app)
.post('/users')
.send({
name: 'Test User',
email: 'test@example.com',
password: 'testpassword'
});
const res = await chai.request(app)
.delete(`/users/${user.body._id}`);
expect(res).to.have.status(200);
expect(res.body).to.be.an('object');
expect(res.body).to.have.property('_id', user.body._id);
});
});
上面的测试使用了chai
和supertest
库,在真实的数据库环境中测试我们的API是否正确工作。我们可以使用以下命令运行测试:
npm run test
REST API是现代Web应用程序的核心组成部分。使用JavaScript和Node.js,我们可以轻松地构建一个完整的REST API,包括路由、控制器、数据库连接和测试。这使得开发和维护Web应用程序变得更加容易和可靠。