我的第一个使用 MERN Stack(后端)的博客 关于我的博客的所有内容:后端 后端博客:如何?

2025-06-07

我的第一个使用 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
Enter fullscreen mode Exit fullscreen mode
  1. 为什么选择 ExpressJS?因为它是NodeJS最流行的框架,而且在找工作时,它是最需要的。

  2. 还有其他 NodeJS 框架吗?当然!我们还有其他很棒的NodeJS框架

  3. 如何在我的服务器文件夹中安装 Express?如果你的文件夹中有package.json文件,只需运行以下命令
    $ npm install --save express

  4. 很难用吗?不,官方文档里有你需要的所有信息


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;
Enter fullscreen mode Exit fullscreen mode

通过这个模式,我们创建了用于存储、保存、删除和读取数据库中的文章的模型。

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"));
Enter fullscreen mode Exit fullscreen mode

哪里可以找到更多关于 Mongoose 的信息? Mongoose 有简单易读的文档。


dotenv

dotenv 是一个 npm 包,允许我们创建环境变量。环境变量是一种动态变量,使用起来非常简单,只需将变量写入 .env 文件并将其用作引用即可。
为什么要这样做?因为当我们将文件上传到存储库或服务器时,我们可以保护变量中的敏感信息或数据(数据库 URL、密码、令牌)。

如何在我的项目中安装 dotenv? $ npm install --save dotenv

如何配置 dotenv 与 de 项目协同工作?只需要在 index.js 顶部添加一行代码即可。

require("dotenv").config();
Enter fullscreen mode Exit fullscreen mode

然后,你可以在项目根目录中创建一个 .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());
Enter fullscreen mode Exit fullscreen mode

关于 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");
        }
      },
    },
Enter fullscreen mode Exit fullscreen mode

你可以在这里看到完整的代码

如何安装验证器? $ 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
};
Enter fullscreen mode Exit fullscreen mode

稍后我们需要一个函数来解密密码以验证密码,为此我创建了一个静态方法。静态方法是模型中可访问的函数,而不是用户对象中可访问的函数

//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.
  }
};
Enter fullscreen mode Exit fullscreen mode

斯拉格菲

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();
});
Enter fullscreen mode Exit fullscreen mode

哪里可以找到更多关于 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
};
Enter fullscreen mode Exit fullscreen mode


结构

我将解释我在项目中使用的结构。

在服务器文件夹中,我在第一级创建了一个 src 文件夹,在这个文件夹里面我创建了五个文件夹,分别名为:

  • 控制器
  • 分贝
  • 中间件
  • 模型
  • 路线

以及两个文件app.jsindex.js


控制器

在这里我创建了路由的控制器,当请求进入服务器时,路径执行一个函数,该函数存储在控制器中。

auth.controller.js -是完整的代码

const authCtrl = {};

authCtrl.registerUser = async (req, res) => {
  // Code
};

authCtrl.loginUser = async (req, res) => {
  // Code
};

module.exports = authCtrl;
Enter fullscreen mode Exit fullscreen mode

数据库

在这里我创建了一个名为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;
Enter fullscreen mode Exit fullscreen mode


结束

这就是我博客的后端,希望您觉得它有趣,并在您不知道如何开始时为您提供指导

文章来源:https://dev.to/rhodlib/my-first-blog-with-mern-stack-back-end-3563
PREV
2021 年用于构建 RESTful API 的 5 大 Node-Express 样板
NEXT
用程序员的大脑思考