使用 Node.Js、ExpressJs、MongoDB 和 VueJs 构建 Todo 应用程序 – 第 1 部分
在本教程中,我们将使用ExpressJs框架和MongoDB ,用 Node.Js 构建著名的待办事项应用程序。我忘了告诉你了吗?该应用程序将以 API 为中心,并且是全栈的 :)。
简而言之,如果您想学习如何使用 Node.Js 构建 API,那么您来对地方了。
现在你可以拿一瓶啤酒,让我们开始行动吧。
什么是 ExpressJs?
ExpressJs 简单来说,就是一个 Node.Js 的 Web 框架——摘自官方文档。Taylor Otwell(Laravel 的创始人)曾经说过:“开发者为开发者构建工具”。ExpressJs 正是为开发者而生,旨在简化 Node API。
什么是 MongoDB?
MongoDB 是一个 NoSQL 数据库。它完全面向文档。NoSQL 数据库允许您以 JSON 格式和任何格式存储数据。如果您想了解更多关于 MongoDB 的信息,我还写了一篇关于 MongoDB 的文章(链接)。
定义 Todo API
我喜欢先定义 API。下表列出了我们需要创建哪些 API 以及每个 API 的功能。
方法 | 小路 | 描述 |
---|---|---|
得到 | /待办事项 | 获取所有待办事项 |
得到 | /todos/:id | 获取一个待办事项 |
邮政 | /待办事项 | 创建新的待办事项 |
放 | /todos/:id | 更新待办事项 |
删除 | /todos/:id | 删除新的待办事项 |
定义了我们的 API 后,让我们深入研究项目目录。
项目目录
当我告诉你,我们只需要不到 5 个文件和相对较少的代码行就能构建这个后端时,你可能会大吃一惊。没错!就是这么简单。我们就是这样做的 :)。
此时您应该创建一个项目文件夹,用于存放此应用程序后端部分的所有源代码。我将其命名为“我的后端”。您可以随意使用backend
作为您的目录。它没有专利。:)
为了保持简单,当然,我们不应该为了追求简单而牺牲灵活性。我们将在您之前创建的目录中仅创建 4 个文件夹。
- config:包含应用程序的配置文件。
- 模型:这是我们的实体(Todo 数据结构)。
- 存储库:存储库在数据访问上添加了一个抽象层。您可以在此处详细了解此层的重要性。
- routes:路由是应用程序的入口。此文件夹包含一个文件,用于定义当用户访问特定路由时应该发生的情况。
├── config
├── models
├── respositories
└── routes
您需要安装什么
申请包
此应用依赖于几个软件包,并将使用 npm 进行安装。导航到刚刚创建的项目目录,并创建一个包含以下内容的package.json文件。
{
"name": "node-todo",
"version": "1.0.0",
"description": "Simple todo application.",
"main": "server.js",
"author": "Samuel James",
"scripts": {
"build": "webpack",
"start": "node app.js"
},
"dependencies": {
"cookie-parser": "~1.4.4",
"cors": "^2.8.5",
"debug": "~2.6.9",
"express": "~4.16.1",
"http-errors": "~1.6.3",
"jade": "~1.11.0",
"mongoose": "^5.7.3",
"morgan": "~1.9.1"
}
}
运行npm install
安装依赖项。让我们继续定义应用程序所需的配置参数。
配置文件
我们将在文件中定义数据库连接 URL 和应用程序将监听的端口,config/Config.js
如下所示:
//config/Config.js
module.exports = {
DB: process.env.MONGO_URL ? process.env.MONGO_URL : 'mongodb://localhost:27017/todos',
APP_PORT: process.env.APP_PORT ? process.env.APP_PORT : 80,
};
在 中config/Config.js
,如果 已定义,则设置DB
为 环境变量,否则默认为。我们对 也做了同样的操作。MONGO_URL
mongodb://localhost:27017/todos
APP_PORT
待办事项模型
模型是数据库中数据的对象表示。因此,让我们创建一个models/Todo.js
包含以下内容的文件:
//models/Todo.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
// Define schema for todo items
const todoSchema = new Schema({
name: {
type: String,
},
done: {
type: Boolean,
},
});
const Todo = mongoose.model('Todo', todoSchema);
module.exports = Todo;
如果你注意到,我们使用 mongoose 来定义模式,对吧?Mongoose 是一个官方的 MongoDB 库,用于在 Node 中操作 MongoDB 数据库。在结构中,我定义了name
和done
。
name:这是待办事项的名称。我们将其定义为字符串。例如,“我打算下午 3 点前去游泳”
。done:待办事项的状态,布尔值。如果待办事项仍处于待处理状态,则其值为 false。
现在,我们将创建一个待办事项存储库。
存储库
我喜欢将存储库视为一种抽象数据访问的策略。当我在一个项目中切换到新的数据存储时,这种模式让我免于繁重的重构,这让我对它产生了浓厚的兴趣。它可以帮助项目解耦,并减少代码重复。这里有一篇关于这种模式的有趣文章,推荐你阅读。
也就是说,创建一个文件repositories/TodoRepository.js作为:
//repositories/TodoRepository
const Todo = require('../models/Todo');
class TodoRepository {
constructor(model) {
this.model = model;
}
// create a new todo
create(name) {
const newTodo = { name, done: false };
const todo = new this.model(newTodo);
return todo.save();
}
// return all todos
findAll() {
return this.model.find();
}
//find todo by the id
findById(id) {
return this.model.findById(id);
}
// delete todo
deleteById(id) {
return this.model.findByIdAndDelete(id);
}
//update todo
updateById(id, object) {
const query = { _id: id };
return this.model.findOneAndUpdate(query, { $set: { name: object.name, done: object.done } });
}
}
module.exports = new TodoRepository(Todo);
定义完成后TodoRepository.js
,我们来创建待办事项路线。
路线
每个 Web 应用至少都有一个入口点。Web 应用中的路由更像是在说:“嘿,Jackson,当我要求你这个时,你就给我那个”。我们的应用也是如此,我们会定义用户需要访问哪些 URL 才能获得特定结果或触发特定操作。
在这种情况下,我们希望用户能够对待办事项执行创建、读取、更新和删除(CRUD)操作。
现在,您知道“routes”的作用了,请创建routes/Routes.js文件并输入以下代码:
const express = require('express');
const app = express.Router();
const repository = require('../respositories/TodoRepository');
// get all todo items in the db
app.get('/', (req, res) => {
repository.findAll().then((todos) => {
res.json(todos);
}).catch((error) => console.log(error));
});
// add a todo item
app.post('/', (req, res) => {
const { name } = req.body;
repository.create(name).then((todo) => {
res.json(todo);
}).catch((error) => console.log(error));
});
// delete a todo item
app.delete('/:id', (req, res) => {
const { id } = req.params;
repository.deleteById(id).then((ok) => {
console.log(ok);
console.log(`Deleted record with id: ${id}`);
res.status(200).json([]);
}).catch((error) => console.log(error));
});
// update a todo item
app.put('/:id', (req, res) => {
const { id } = req.params;
const todo = { name: req.body.name, done: req.body.done };
repository.updateById(id, todo)
.then(res.status(200).json([]))
.catch((error) => console.log(error));
});
module.exports = app;
首先,您希望用户获取数据库中所有待办事项的列表,因此我们定义了一个路由(/all),该路由接受获取请求并在成功时返回待办事项的 JSON 对象。
我们的用户喜欢获取物品以及存储新物品,因此我们添加了一个用于创建新待办事项的路由。它接受 post 请求。
当 A 先生向路由发出 post 请求 ( /add ) 时,数据库中就会创建一个新的待办事项。
待办事项完成后,我们希望用户能够将其标记为已完成。为此,首先必须知道用户想要将哪个事项标记为已完成。因此,我们定义了一个“更新路由”,其路由参数是待更新事项的 ID。
服务器文件
定义了应用程序所需的所有路由后,就该创建一个入口文件了,它是运行我们项目的主文件。
在项目根文件夹中,创建一个app.js文件并使用以下内容更新其内容:
//app.js
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const cors = require('cors')
const config = require('./config/Config');
const routes = require('./routes/Routes');
const app = express();
mongoose.connect(config.DB, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
app.use(cors()); //enable cors
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/todos', routes);
// catch 404 and forward to error handler
app.use((req, res, next) => {
next(createError(404));
});
// error handler
app.use((err, req, res) => {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
app.listen(config.APP_PORT); // Listen on port defined in environment
module.exports = app;
我们要求:
-
Express JS
-
morgan - Node 的日志中间件
-
path -用于处理文件和目录的包
-
mongoose -用于 MongoDB 的软件包
-
body-parser -一个 正文解析中间件
我们将应用设置为监听 config/Config.js 中设置的端口。我们还定义了它使用routes/Routes.js中定义的路由,并在其前面加上todos前缀。
最后,您的目录结构应如下所示:
├── app.js
├── config
│ └── Config.js
├── models
│ └── Todo.js
├── package-lock.json
├── package.json
├── respositories
│ └── TodoRepository.js
└── routes
└── Routes.js
要启动应用程序,请导航到项目根目录并运行:
npm start
让我们创建一个新的待办事项
$ curl -H "Content-Type: application/json" -X POST -d '{"name":"Going Shopping"}' http://localhost/todos
{"__v":0,"name":"Going Shopping","done":false,"_id":"5a6365a39a2e56bc54000003"}
获取所有待办事项
$ curl http://localhost/todos
[{"_id":"5a6365a39a2e56bc54000003","name":"Doing Laundry","done":false,"__v":0},{"_id":"5a6366039a2e56bc54000004","name":"Going Shopping","done":false,"__v":0}]
搭建完成了吗?快来看看第二部分吧。
文章来源:https://dev.to/abiodunjames/build-a-todo-app-with-nodejs-expressjs-mongodb-and-vuejs--part-1--29n7