NodeJS + Express 第 5 部分:路由和控制器

2025-06-08

NodeJS + Express 第 5 部分:路由和控制器

这里有一系列文章可以帮助您使用 NodeJS + Express 创建后端应用程序。

本系列是我 NodeJS 基础系列的延续。如果你对 NodeJS 还不了解,可以先阅读以下系列:NodeJS 入门

Node.js 如今已成为必需品,因此开发人员必须掌握它。

因此,我将每两天发布一篇新文章,逐渐地您将了解有关 Node.js + Espress 的所有知识

为了不错过任何内容,请在 Twitter 上关注我:https://twitter.com/EricTheCoder_


Express路由器

正如你在上一篇文章中所见,使用 Express 创建 CRUD API 很容易。但你现在应该已经注意到,所有代码都放在同一个文件中非常臃肿,我们很快就会迷失方向。

按照惯例,Express 开发人员将代码拆分到不同的文件和文件夹中,以优化代码组织。

首先也是最明显的事情是拆分路线和路线实现代码。

这是我们在上一篇文章中使用的一个例子

app.get('/api/products/:productID', (req, res) => {
    const id = Number(req.params.productID)
    const product = products.find(product => product.id === id)

        if (!product) {
        return res.status(404).send('Product not found')
    }
    res.json(product)
})
Enter fullscreen mode Exit fullscreen mode

这里的目标是拆分路由及其实现代码。为此,我们可以使用 Express 包中的 Router 调用

路由器帮助创建所有应用程序路由的列表,并将它们关联到包含实现代码的控制器文件。

第一步是创建一个文件来存放我们所有的应用路由。例如:/routes/products.js 可以包含所有与产品资源相关的路由。

下一步,我们将创建一个控制器文件来存放所有路由实现代码。例如:/controllers/products.js

从我之前的文章开始,这里有一个路线和控制器文件的示例。

路线/产品.js

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

const  { 
    getProducts,
    getProduct,
    createProduct,
    updateProduct,
    deleteProduct 
} = require('../controllers/products.js')

router.get('/', getProducts)

router.get('/:productID', getProduct)

router.post('/', createProduct) 

router.put('/:productID', updateProduct) 

router.delete('/:productID', deleteProduct)

module.exports = router
Enter fullscreen mode Exit fullscreen mode

正如您所见,实现非常简单和直接。

首先创建 Router 对象的实例

然后导入所有控制器功能。

最后,使用路由器对象创建路由和控制器关联。


以下是控制器函数controllers/products.js的示例

const products = require('../data.js')

const getProducts = ((req, res) => {
    res.json(products)
})

const getProduct = ((req, res) => {
    const id = Number(req.params.productID)
    const product = products.find(product => product.id === id)

        if (!product) {
        return res.status(404).send('Product not found')
    }
    res.json(product)
})

const createProduct = ((req, res) => {
    const newProduct = {
        id: products.length + 1,
        name: req.body.name,
        price: req.body.price
    }
    products.push(newProduct)
    res.status(201).json(newProduct)
})

const updateProduct = ((req, res) => {
    const id = Number(req.params.productID)
    const index = products.findIndex(product => product.id === id)
    const updatedProduct = {
        id: products[index].id,
        name: req.body.name,
        price: req.body.price
    }

    products[index] = updatedProduct
    res.status(200).json('Product updated')
})

const deleteProduct = ((req, res) => {
    const id = Number(req.params.productID)
    const index = products.findIndex(product => product.id === id)
    products.splice(index,1)
    res.status(200).json('Product deleted')
})

module.exports = {
    getProducts,
    getProduct,
    createProduct,
    updateProduct,
    deleteProduct
}
Enter fullscreen mode Exit fullscreen mode

这里没有什么新东西,它是相同的实现,但是代码现在位于带有 req 和 res 参数的单独函数中。

一旦创建了路由和控制器文件,我们需要告诉 Express 使用这些路由

从主文件中添加一个 app.use() 并引用我们的路由

const express = require('express')
const app = express()
const products = require('./data.js')
const products_routes = require('./routes/products.js')

app.listen(5000, () => {
    console.log('server is listening on port 5000')
})

app.use(express.json())
app.use('/api/products', products_routes)
Enter fullscreen mode Exit fullscreen mode

请注意,app.use() 在“/api/products”中具有路由前缀,这意味着路由文件中的所有 url 路径将自动包含该前缀。

结论

今天就到这里,请在推特上关注我:https://twitter.com/EricTheCoder_以便收到下一篇文章发布的通知(两天内)。

鏂囩珷鏉ユ簮锛�https://dev.to/ericchapman/nodejs-express-part-5-routes-and-controllers-55d3
PREV
React(正在进行中)备忘单
NEXT
我心爱的 Ruby 速查表