我的第一个使用 MERN Stack(后端)的博客
关于我的博客:后端
后端博客:怎么样?
关于我的博客:后端
后端博客:怎么样?
在本文中,我将解释我是如何创建博客后端的,
使用了哪些技术以及原因。这不是一个循序渐进的指南,只是在你不知道如何开始创建自己的博客时的一个资源,或许可以帮助你学习你需要学习的技术。互联网上的信息量很大,有时很难找到问题的正确答案。
我后端的所有代码都在这里
指数
- 依赖项
- ExpressJS
- 猫鼬
- dotenv
- 科尔斯
- 验证器
- bcryptjs
- jsonwebtoken
- slugify
- 数据库
- MongoDB
- 结构
- 控制器
- 分贝
- 中间件
- 模型
- 路线
依赖项
我将用几句话尝试解释这些依赖关系以及我使用它们的原因。
ExpressJS
我们用来制作这个博客的语言是JavaScript,因此我使用NodeJS作为后端,NodeJS允许我们在服务器端运行JavaScript 。
ExpressJS只不过是NodeJS的一个 Web框架,它非常强大并且具有许多功能,可以让我们在使用NodeJS时更加轻松,例如,它允许我们用 6 行或更少的代码来配置服务器。
const express = require("express"); // 1
const app = express(); // 2
app.listen(3000, function () {
// 3
console.log("Server listening on port 3000"); // 4
}); //5
-
为什么选择 ExpressJS?因为它是NodeJS最流行的框架,而且在找工作时,它是最需要的。
-
还有其他 NodeJS 框架吗?当然!我们还有其他很棒的NodeJS框架。
-
如何在我的服务器文件夹中安装 Express?如果你的文件夹中有package.json文件,只需运行以下命令
$ npm install --save express
-
很难用吗?不,官方文档里有你需要的所有信息
Mongoose 和 MongoDB
正如官方网站所说,mongoose是一个为NodeJS优雅的mongodb对象建模,这是什么意思呢?
嗯,MongoDB是一个NoSQL(不仅仅是 SQL)数据库系统,
是一个基于文档的数据库,我们可以在文档中以
JSON (JavaScript 对象表示法)格式存储信息,并且这些文档保存在MongoDB提供的 ID 的集合中。
但是,我们唯一能保持数据库数据有序进出的方法是mongoose。它有创建 Schema 和模型的功能。
什么是 Schema? Schema 是一个对象,它允许我们在将数据发送到数据库之前声明某些值并生成验证。从而允许我们在存储的所有数据中管理相同的结构。
这是我的博客文章的架构,这是文章存储到数据库的方式
const { Schema, model } = require("mongoose");
const postSchema = new Schema(
{
image: String,
title: {
type: String,
required: true,
},
description: String,
markdown: {
type: String,
required: true,
},
createdAt: {
type: Date,
default: Date.now,
},
slug: {
type: String,
required: true,
unique: true,
},
},
{
timestamps: true,
}
);
const Post = model("Post", postSchema);
module.exports = Post;
通过这个模式,我们创建了用于存储、保存、删除和读取数据库中的文章的模型。
Mongoose还允许我们以非常简单的方式连接到数据库。
const mongoose = require("mongoose");
const URI = "mongodb://localhost/dbtest";
mongoose.connect(URI);
const connection = mongoose.connection;
connection.once("open", () => console.log("DB is connected"));
哪里可以找到更多关于 Mongoose 的信息? Mongoose 有简单易读的文档。
dotenv
dotenv 是一个 npm 包,允许我们创建环境变量。环境变量是一种动态变量,使用起来非常简单,只需将变量写入 .env 文件并将其用作引用即可。
为什么要这样做?因为当我们将文件上传到存储库或服务器时,我们可以保护变量中的敏感信息或数据(数据库 URL、密码、令牌)。
如何在我的项目中安装 dotenv? $ npm install --save dotenv
如何配置 dotenv 与 de 项目协同工作?只需要在 index.js 顶部添加一行代码即可。
require("dotenv").config();
然后,你可以在项目根目录中创建一个 .env 文件。有关 dotnev 的更多信息,请点击此处
科尔斯
Cors 很简单,我使用它是因为它可以让我在不同的端口上同时拥有两个服务器,并且能够在它们之间进行通信,后端服务器使用 nodemon,前端服务器使用 npm start
如何安装cors? $ npm install --save cors
如何使用 cors?在服务器的 index.js 中,或者在你的应用程序所在的任何地方
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors());
关于 cors 的更多信息请点击此处
验证器
validator 是一个字符串验证器和清理器库
我在 User 模型上使用它来验证 userSchema 中的电子邮件属性
const validator = require("validator");
email: {
type: String,
required: true,
unique: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error("Email is invalid");
}
},
},
你可以在这里看到完整的代码
如何安装验证器? $ npm install --save validator
在哪里可以了解更多关于验证器的信息?您可以在这里阅读更多
bcryptjs
bcryptjs 是一个用于加密的 npm 包,我用它来加密密码,它非常易于使用且安全,每周下载量超过 70 万次。
如何安装 bcryptjs? $ npm install --save bcryptjs
我如何使用 bcryptjs?
我在“用户模型”的两个功能中使用了bcrypt,一个是通过userSchema为用户模型创建一个方法来加密密码。
User.js -这是所有代码
const bcrypt = require("bcryptjs");
//Here i created a method for userSchema called encryptPassword
userSchema.methods.encryptPassword = async (password) => {
// get the password
return await bcrypt.hash(password, 8); // 8 is a cicle this been hashed 8 times
// and then return the password hashed by a function of bcrypt
};
稍后我们需要一个函数来解密密码以验证密码,为此我创建了一个静态方法。静态方法是模型中可访问的函数,而不是用户对象中可访问的函数
//Here i created a static method to find credentials and validate password
userSchema.statics.findByCredentials = async (email, password) => {
//Get email and password
const user = await User.findOne({ email }); //Search by email using the model (findOne is a static method)
if (user) {
// If user exist
const isMatch = await bcrypt.compare(password, user.password);
// use a function called compare from bcrypt and compare the password with the user.password in the database.
}
};
斯拉格菲
Slugify 是一个 npm 包,用于从字符串创建 slug。
slug 到底是什么鬼? slug 可不是像“你好,你好吗”这样简单的字符,它是一个用破折号代替空格的字符串。
为什么我需要 slug?在这个博客里,我把 slug 当作每篇文章的一个唯一属性,用它的标题作为 slug。为什么?因为我可以用 slug 搜索文章,而不需要通过 ID。
这是最好的解决方案吗?不是,因为最佳实践是使用 ID,但这对我来说是正确的。
slug 如何帮助你?很简单,通过 id 查找,前端的路由是这样的,blog.rhodlib.me/article/5468fds1684541sdf18546516s8
这很不美观,看起来也不好看。
但如果通过 slug 查找,路由是这样的blog.rhodlib.me/article/all-about-my-blog-backend-how
如何安装 slugify? $ npm install --save slugify
如何使用 slugify?非常简单,我们来看看。
Post.js这里是全部代码。
const slugify = require("slugify");
//the function pre of the postSchema allows us run a function between the validate and the store article on the database
postSchema.pre("validate", function (next) {
const post = this;
if (post.title) {
post.slug = slugify(post.title, { lower: true, strict: true }); // We use slugify to create the slug with the title, before save the article in the database
}
next();
});
哪里可以找到更多关于 slugify 的信息?你可以去这里
jsonwebtoken
jsonwebtoken 是用于创建验证令牌的库,我使用它来验证用户在应用程序中连接时的情况。
如何在博客中使用 JWT?我使用的方式如下。
User.js -这是完整代码
const jwt = require("jsonwebtoken");
// here i created a method for each User called generateAuthToken
userSchema.methods.generateAuthToken = async function () {
const user = this;
const token = jwt.sign(
// With jwt.sing() we create a token
{ _id: user._id.toString() }, // I pass the user id in an object
process.env.AUTHTOKENSTRING // I use an environment variable to encrypt the token with a secret word
);
user.tokens = user.tokens.concat({ token }); // And then I put the new token in the user's token array
};
结构
我将解释我在项目中使用的结构。
在服务器文件夹中,我在第一级创建了一个 src 文件夹,在这个文件夹里面我创建了五个文件夹,分别名为:
- 控制器
- 分贝
- 中间件
- 模型
- 路线
以及两个文件app.js和index.js
控制器
在这里我创建了路由的控制器,当请求进入服务器时,路径执行一个函数,该函数存储在控制器中。
auth.controller.js -这是完整的代码
const authCtrl = {};
authCtrl.registerUser = async (req, res) => {
// Code
};
authCtrl.loginUser = async (req, res) => {
// Code
};
module.exports = authCtrl;
数据库
在这里我创建了一个名为mongoose.js的文件并使用 mongoose 存储我对数据库的访问。
中间件
在这里我创建了我的中间件,只有一个。auth.js,用于实现登录的授权。
模型
在这里我创建了两个模型,它们都有自己的模式。
路线
这里我创建了请求的路由。我有三个文件,每个文件都详细说明了路由:
- auth.routes.js
- post.routes.js
- 用户.routes.js
auth.routes.js -这是完整的代码
const { loginUser } = require("../controllers/auth.controller");
router.post("/api/user/login", loginUser);
module.exports = router;
结束
这就是我博客的后端,希望您觉得它有趣,并在您不知道如何开始时为您提供指导
文章来源:https://dev.to/rhodlib/my-first-blog-with-mern-stack-back-end-3563