ExpressJS:分离路线和接受参数的最佳方式?

ExpressJS: Best way to separate routes and accepting params?

我制作了一个 Express.js 系统,其中 /routes 文件夹中的文件充当经典路由(但每个路由一个文件)

示例:/routes/get/user.js 将可以通过 http://localhost:8080/user 访问(/get 用于分隔方法,可以是 /post/put... )

这是我的整个 index.js 文件:https://pastebin.com/ALtSeHXc

但实际上,我的问题是我无法将参数传递到 url 中,例如 https://localhost:8080/user/random_id_here

有了这个系统,我认为最好的办法是找到一种方法也可以在分离的文件上传递参数,但我不知道该怎么做...

这是我的一个分离文件的示例:

module.exports = class NameAPI {
    constructor(client) {
        this.client = client
    }

    async run(req, res) {
        // Code here
    }
}

也许您会有更好的系统,或者解决方案。谢谢。

如果您需要动态插入,我通常会设置我的快递以这种方式处理。这是个人代码,因此请进行必要的调整或观察行为! :)

WEBAPP.get('/room/:name', (req, res) => {
  // Check if URL ends with / (in my case I don't want that)
    if (req.url.endsWith('/')) return res.redirect('/');
  // Check if URL param "name" matches my regex ex. Username1920 or redirect them
    if (req.params.name.match(/^[a-zA-Z0-9]{3,24}$/) === null) return res.redirect('/');
  // render the room (sending EJS)
    res.render('room', {
        title: req.params.name.toUpperCase()
    });
});
/*

/*This example accepts one param and must follow my regex/rules*/

因此,如果您被交给​​ /room/test12345,您的 req.params.name 将 return 一个值。注意冒号定义了一个参数,所以你可以有 /:room/:user/:request 并且它会 return: req.params.room、req.params.user、req.params.request全部定义! :)

您可以从已有的模块对象中获取可选参数,因此每个模块都指定了自己的参数。下面的示例显示了在模块名称后仅添加新参数,但如果需要,您可以扩展此功能以使其更丰富。

在一个简单的实现中,在你的加载器中,你可以改变这个:

   posts.forEach((post) => {
        const module = new (require(`./routes/post/${post}`))(this);
        this.api.post(`/${post}`, async (req, res) => await module.run(req, res))
    })

对此:

   posts.forEach((post) => {
        const module = new (require(`./routes/post/${post}`))(this);
        const urlParams = module.params || "";
        this.api.post(`/${post}${urlParams}`, async (req, res) => module.run(req, res))
    });

所以,如果给定的路由想要添加额外的 URL 参数 /:id,那么它只需在其导出的模块对象上定义 .urlParams 属性是 `"/:id" 并且会自动包含在路由定义中。


P.S。 _loadHttpMethode() 中的 switch 语句的每个分支中的大部分代码都是相同的。通过对一个公共函数进行一些分解并将一个或两个参数传递给该函数,您可以消除开关的这些不同分支之间的所有复制代码,因此每个开关所做的只是调用一个函数并向其传递一些参数。

如何在 express 中分离路由和解析请求参数 API

您可以将每个模型的所有不同 API 方法放在一个单独的文件夹中,然后只解析主文件中的 API 路由。

假设我们有一个名为 app.js 的主文件,您可以在子文件夹中整理 API routes/endpoints。

文件夹结构:

├── app.js
└── routes
    └── api
        └── users.js
在本例中,文件夹 routes/api 中的

users.js 包含用户端点的所有操作,您将其导入到 app.js 文件中。

根据下面定义的路由示例,这将让您使用这些端点解析您的 express API:

GET YOUR_API:PORT/users           // fetch all users
GET YOUR_API:PORT/users/:userId   // fetch single user by id

app.js

// this is just a demo app.js, please adapt to your needs
const express = require("express");

// express app
const app = express();
app.use(express.json());

// api routes
// endpoint No. 1, this will create the endpoint /users
// and will enable you to use all methods defined in file users.js
app.use("/users", require("./routes/api/users"));

// add more endpoints, example endpoint No. 2
app.use("/ENDPOINT_NAME", require("./routes/api/FILE_NAME"));

// handle everything else you need to handle in your main file

// run server
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

在子文件夹 routes/api 中添加 api 路由文件,如下所示:

routes/api/users.js

const express = require('express');
const router = express.Router();

// here we only GET all users and user by id, 
// but you can add any endpoints required for your API.

// get all users
router.get('/', async (req, res) => {
    try {
        // do something to get all users
        const allUsers = // fetch all users, depends on how you want to do it
        return res.status(200).json(allUsers)
    } catch (err) {
        console.log(err)
        return res.status(400).json({ msg: 'Bad request.' })
    }
})

// get a specific user by Id from request parameters
router.get('/:userId', async (req, res) => {
    try {
        // user id from params
        const userId = req.params.userId
        // do something with this userId, for example look up in DB
        return res.status(200).json({userId: `Requested userId is ${userId}`})
        )        
    } catch (err) {
        console.log(err)
        return res.status(400).json({ msg: 'Bad request.' })
    }
})

// add more user endpoints here
// with router.post, router.put, router.delete, whatever you need to do

module.exports = router