We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Koa 中可以使用 app.use 注册中间件, 中间件接收一个 ctx 参数, 这个参数挂载了一些请求信息, 同时返回给前端的信息也可以挂载在这个参数上
app.use
ctx
那么我们就可以这样处理路由:
app.use(async (ctx, next) => { if(ctx.path === 'user' && ctx.method.toUpperCase() === 'GET'){ ctx.body = { 'name': "john" } } })
如果我们希望路由这块能抽离出来呢? 这样会比较好维护一些, 这时可以使用 koa-router, 因为 koa 默认没有集成, 所以需要单独安装
koa-router
在 router.js 中编写路由中间件
const KoaRouter = require('koa-router') const router = new KoaRouter() router.get('/user', async (ctx, next) => { // 这里的路由处理函数实际上也是一个中间件 // ... 路由处理 await next() }) router.get('/user', async (ctx, next) => { next() }) router.get('/msg', async (ctx, next) => { next() })
可以看到, koa-router 对路由的处理, 实际上也遵循洋葱圈模型, 这样的好处是: 可以将路由抽离成一个中间件
只需要引用这个路由中间件即可
import router from 'router.js' app.use(router.routes())
接下来我们应该思考的是, 当项目越来越大的时候, 我们总不能把所有的路由处理都放在一个 router.js 里面吧, 对不同主题的路由进行进一步的拆分是很有必要的
router.js
比如一个博客系统, 就可以拆分成 user 部分, blog 部分, love 点赞部分等。 除此之外, 我们还要考虑新版本旧版本路由的兼容问题, 这时候又要将进行进一步划分。如果将所有路由都写在一个文件里面的话, 简直是灾难!
这时候我们的目录拆分大概是这样的, 用 v 表示版本号:
拆分好了, 新的问题又来了, 如果我们拆分了这么多块, 那岂不是要在 app.js 这个入口文件也引入这么多
app.js
像这样:
const User_v1 = require('api/v1/user') const Blog_v1 = require('api/v1/blog') const Love_v1 = require('api/v1/love') const User_v2 = require('api/v2/user') const Blog_v2 = require('api/v2/blog') const Love_v2 = require('api/v2/love') app.use(User_v1) app.use(Blog_v1) // ... 写不下去了
这时候我们可以借助一个第三方的包 require-directory , 他可以帮我们自动获取指定目录下所有文件导出的 module, 值得一提的是, 即使是嵌套的目录, 他也可以检索出来。
require-directory
module
const KoaRouter = require('koa-router') const requireDirectory = require('require-directory') // 检索 /api 下的每一个文件导出的 module, 每导入一个 module, 都会执行 whenLoadModule 函数, 并且将导出的 module.exports 作为参数传给这个函数 requireDirectory(module, '/api', { visit: whenLoadModule }) function whenLoadModule(exports){ // 导出的 module.exports // 这里统一规定 modulex.exports 导出的形式为对象形式 { xxx, yyy }, 方便统一处理 Object.keys(exports).forEach(k => { // 只要是路由对象就进行注册 if(exports[k] instanceof KoaRouter){ app.use(exports[k].routes()) } }) }
现在我们注册路由已经很方便了, 但是还是觉得 app.js 的代码有点多, 对于这些初始化的代码, 我们可以用一个类抽象一下:
// core/init.js const KoaRouter = require('koa-router') const requireDirectory = require('require-directory') class InitManager { static init(app){ InitManager.app = app InitManager.initRouters() } static initRouters(){ // 这里我们路径用拼接的绝对路径, 硬编码的话改动很麻烦 const apiDirectory = `${process.cwd()}/api` requireDirectory(module, apiDirectory, { visit: whenLoadModule }) function whenLoadModule(exports){ Object.keys(exports).forEach(k => { if(exports[k] instanceof KoaRouter){ InitManager.app.use(exports[k].routes()) } }) } } } module.exports = InitManager
这时候我们的 app.js 就比较清爽了
const Koa = require('koa') const InitManager = require('core/init') const app = new Koa() InitManager.init(app)
到这里, 我们的路由处理的大体框架就基本完善了
The text was updated successfully, but these errors were encountered:
No branches or pull requests
koa 中的路由
Koa 中可以使用
app.use
注册中间件, 中间件接收一个ctx
参数, 这个参数挂载了一些请求信息, 同时返回给前端的信息也可以挂载在这个参数上那么我们就可以这样处理路由:
如果我们希望路由这块能抽离出来呢? 这样会比较好维护一些, 这时可以使用
koa-router
, 因为 koa 默认没有集成, 所以需要单独安装在 router.js 中编写路由中间件
可以看到,
koa-router
对路由的处理, 实际上也遵循洋葱圈模型, 这样的好处是: 可以将路由抽离成一个中间件只需要引用这个路由中间件即可
接下来我们应该思考的是, 当项目越来越大的时候, 我们总不能把所有的路由处理都放在一个
router.js
里面吧, 对不同主题的路由进行进一步的拆分是很有必要的比如一个博客系统, 就可以拆分成 user 部分, blog 部分, love 点赞部分等。
除此之外, 我们还要考虑新版本旧版本路由的兼容问题, 这时候又要将进行进一步划分。如果将所有路由都写在一个文件里面的话, 简直是灾难!
这时候我们的目录拆分大概是这样的, 用 v 表示版本号:
拆分好了, 新的问题又来了, 如果我们拆分了这么多块, 那岂不是要在
app.js
这个入口文件也引入这么多像这样:
这时候我们可以借助一个第三方的包
require-directory
, 他可以帮我们自动获取指定目录下所有文件导出的module
, 值得一提的是, 即使是嵌套的目录, 他也可以检索出来。现在我们注册路由已经很方便了, 但是还是觉得
app.js
的代码有点多, 对于这些初始化的代码, 我们可以用一个类抽象一下:这时候我们的
app.js
就比较清爽了到这里, 我们的路由处理的大体框架就基本完善了
The text was updated successfully, but these errors were encountered: