什么是路由

路由就是具体的访问路径,指向特定的功能模块。一个api接口是由ip(域名)+端口号+路径组成,例如 :https://www.npmjs.com/package/koa-router就是一个路由,指向了koa-routernpm页面。

为什么需要 koa-router 路由

当然不需要koa-router也能实现路由功能,通过ctx.request.path去指定路径实现。例子如下:

const koa = require('koa2')
const app = new koa() app.use(async (ctx, next) => {
if (ctx.request.path === '/') { // 首页
ctx.response.status = 200
ctx.response.body = 'index'
} else if (ctx.request.path === '/list') { // 列表页
ctx.response.status = 200
ctx.response.body = 'list'
} else {
ctx.throw(404, 'Not found') // 404
}
await next()
}) app.listen(3000)

参考:Koa 路由

以上代码只是实现两个接口,就写了不少代码,而写是多层的判断代码,可读性已经很差了,这时候怎么办?

是不是可以将以上代码抽取出去,通过中间件的方式去实现。

结果是可以的,koa-router就是这样做的。使用koa-router实现的例子如下:

  1. app.js 入口
  2. urls/home.js home 页面的路由

app.js 的代码如下

// 路由模块使用前需要先安装和实例化
const Router = require('koa-router')
const router = new Router() // 首页
app.use(async (ctx, next) => {
if (ctx.request.path === '/') {
ctx.response.status = 200
ctx.response.body = 'index'
}
await next()
}) // 其他页面通过 router 加载
let urls = fs.readdirSync(__dirname + '/urls')
urls.forEach((element) => {
let module = require(__dirname + '/urls/' + element)
/*
urls 下面的每个文件负责一个特定的功能,分开管理
通过 fs.readdirSync 读取 urls 目录下的所有文件名,挂载到 router 上面
*/
router.use('/' + element.replace('.js', ''), module.routes(), module.allowedMethods())
})
app.use(router.routes())

urls/home.js 的代码如下

const Router = require('koa-router')
const home = new Router() // /home
home.get('/', async (ctx, next) => {
ctx.response.status = 200
ctx.response.body = 'home'
await next()
}) // home/list
home.get('/list', async (ctx, next) => {
ctx.response.status = 200
ctx.response.body = 'home-list'
await next()
}) module.exports = home

通过以上代码基本已经实现了全局路由的功能了,剩下得就是在urls包下创建对应的文件即可,参考home.js即可。

但是这里的代码还是不够完美,app.js作为入口文件,这里的代码还是有点多了;而且首页和home的路由是分开来实现的。再而且urls路径是固定的,后续文件夹名称或者位置改变都会出现问题。

那么如何实现呢?

这里介绍一种思路:

  1. app.js中的代码抽取出来,让app.js尽量简单
  2. 将首页和其他页面都在全局路由中实现

优雅的全局路由实现

通过npm引入require-directory

require-directory npm包的作用是:

递归地遍历指定目录,对每个文件进行require()

这里也是利用了这个包去实现的。具体实现如下:

  1. core目录下创建InitManager.js
const requireDirectory = require('require-directory')
const Router = require('koa-router')
/**
* 加载全局路由
*/
static initLoadRouters(app){
// 加载工作目录下的 app/api 下的路径
const apiDirectory = `${process.cwd()}/app/api` // 参数:第一个参数固定参数module
// 第二个参数要加载的模块的文件路径
// 第三个参数:每次加载一个参数执行的函数
requireDirectory(module, apiDirectory, {
visit: whenLoadModule
}) function whenLoadModule(obj) {
if(obj instanceof Router ){
app.use(obj.routes())
}
}
} module.exports = InitManager

从上面的实现方式可以看出这里使用了process.cwd()获取路径,而原有的代码中是通过__dirname去获取路径,那么二者有什么区别呢?

NodeJsprocess.cwd()__dirname的区别

process.cwd() 是当前执行node命令时候的文件夹地址 ——工作目录,保证了文件在不同的目录下执行时,路径始终不变

__dirname 是被执行的js 文件的地址 ——文件所在目录

  1. app.js中加载这个方法即可。
const app = new Koa()
InitManager.initLoadRouters(app)
  1. app/api下创建相应的接口文件即可,如home.js

咨询请加微信:轻撩即可。

全栈项目|小书架|服务器开发-Koa全局路由实现的更多相关文章

  1. 全栈项目|小书架|服务器开发-Koa2 全局异常处理

    什么是异常 做开发的基本都知道异常,像Android开发中常见的ANR异常.空指针异常,服务器开发中经常遇到的异常404,500异常,还有一些其他常见的异常,具体可见HTTP状态码. 基本上这些异常可 ...

  2. 全栈项目|小书架|服务器开发-NodeJS 使用 JWT 实现登录认证

    通过这篇 全栈项目|小书架|服务器开发-JWT 详解 文章我们对JWT有了深入的了解,那么接下来介绍JWT如何在项目中使用. 安装 $ npm install jsonwebtoken 生成 Toke ...

  3. 全栈项目|小书架|服务器开发-NodeJS 项目分包

    唠嗑 参考的是慕课网七月老师的课程,七月的课质量真的挺高的,推荐一波.这次的小书架项目源码不会全部公开,因为用了七月老师课程的绝大部分代码.虽然代码不全,但是只要思路看得懂,代码实现就很简单了. 小书 ...

  4. 全栈项目|小书架|服务器开发-JWT 详解

    JWT 官方简介:Introduction to JSON Web Tokens 文章基本是官网内容的翻译,英文不错的同学可点击上面的链接直接看英文文档. 什么是 JWT JWT全称是JSON Web ...

  5. 全栈项目|小书架|服务器开发-Koa2中间件机制洋葱模型了解一下

    KOA2 是什么? Koa是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小.更富有表现力.更健壮的基石. 通过利用 asyn ...

  6. 全栈项目|小书架|服务器开发-Koa2 连接MySQL数据库(Navicat+XAMPP)

    为什么使用数据库 为什么需要数据库?-知乎 相比与文件系统,数据库具有以下优势: 高效率:查找效率高 高可用:可数据库共享 安全性强:数据不能随意修改 选择哪个数据库 数据库可以分为关系型数据库和非关 ...

  7. 全栈项目|小书架|服务器开发-Koa2 参数校验处理

    为什么需要做参数校验 在开发中,无论是App开发还是服务器接口开发, 我们无法去预测用户传入的数据,因此参数(数据)校验是开发中不可或缺的一环. 例如像App的注册登录表单提交页面,就要做好多层的判断 ...

  8. 全栈项目|小书架|服务器开发-NodeJS 中使用 Sequelize 操作 MySQL数据库

    安装 官网:https://sequelize.org/v5/manual/getting-started.html 安装sequelize及数据库连接驱动 npm install --save se ...

  9. 全栈项目|小书架|服务器端-NodeJS+Koa2实现首页图书列表接口

    通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 首页书籍信息 先来回顾一下首页书籍都有哪些信息: 从下面的图片可以看 ...

随机推荐

  1. lintcode 394. Coins in a Line 、leetcode 292. Nim Game 、lintcode 395. Coins in a Line II

    变型:如果是最后拿走所有石子那个人输,则f[0] = true 394. Coins in a Line dp[n]表示n个石子,先手的人,是必胜还是必输.拿1个石子,2个石子之后都是必胜,则当前必败 ...

  2. 终于解决了python 3.x import cv2 “ImportError: DLL load failed: 找不到指定的模块” 及“pycharm关于cv2没有代码提示”的问题

    终于解决了python 3.x import cv2 “ImportError: DLL load failed: 找不到指定的模块” 及“pycharm关于cv2没有代码提示”的问题   参考 :h ...

  3. 安装DEDECMS出现Function ereg_replace()错误的解决方法

    这个问题我记得以前有遇到的,是在本地调试dedecms整站程序的时候,从网上下载了一个整套程序包括模板到本地调试,导入数据库安装都正常,但是登陆 后台就出现"Deprecated: Func ...

  4. 深入学习c++--lambda函数

    1. 简单使用 #include <iostream> #include <functional> using namespace std; struct Print { vo ...

  5. Qt编写气体安全管理系统16-云端同步

    一.前言 云端同步功能是为了后期的拓展做准备的,他的目的就是将本地的数据库中的记录,比如实时采集到的数据以及存储的运行记录等,同步到云端数据库上,默认采用阿里云的mysql数据库,阿里云速度还是挺快的 ...

  6. Linux记录-limits.conf 配置

    limits.conf 文件实际是 Linux PAM(插入式认证模块,Pluggable Authentication Modules)中 pam_limits.so 的配置文件,而且只针对于单个会 ...

  7. CentOS7下yum安装Redis

    (1).Redis概述 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value(键值型)数据库(非关系型数据库),并提供多种语言的API. Redi ...

  8. python对 windows系统监控插件

    在python编程的windows系统监控中,需要监控监控硬件信息需要两个模块:WMI 和 pypiwin32 .

  9. VS2010/VS2012/VS2015下openGL环境配置(转)

    按:按照下述博文,三个例子均成功. https://blog.csdn.net/so_geili/article/details/51685005 请仔细阅读每一个字. 为了学习<OpenGL超 ...

  10. 【物联网】arduino wifi

    https://www.arduino.cn/forum.php?mod=viewthread&tid=49561 http://dy.163.com/v2/article/detail/DC ...