Koa2项目实战2(路由管理、项目结构优化)

news2025/2/4 10:32:32

添加路由(处理不同的URL请求)

路由:根据不同的URL,调用对应的处理函数。

每一个接口服务,最核心的功能是:根据不同的URL请求,返回不同的数据。也就是调用不同的接口返回不同的数据。

在 Node.js 中使用 Koa 框架添加路由可以通过以下几种方式实现:

第1种:使用原生的 app.use 和条件判断

// 导入koa, koa是一个类
const Koa = require('koa')

const { APP_PORT } = require('./config/config.env')

// 创建koa实例对象:app
const app = new Koa()

// 使用 app.use() 方法添加中间件,且只能写一个中间件
app.use((ctx, next) => {
  // 中间件逻辑
  if (ctx.url === '/home') {
    ctx.body = 'This is the home page';
  } else if (ctx.url === '/about') {
    ctx.body = 'This is the about page';
  } else {
    ctx.body = 'Page not found';
  }
});

// 指定端口号并启动服务器
app.listen(APP_PORT, () => {
  console.log(`server is running on http://localhost:${APP_PORT}`)
})

第2种:使用第三方路由模块,如 koa-router(常用)

koa-router API

安装koa-router

npm install koa-router -D

API 介绍

const Router = require('koa-router');
const router = new Router();
  • new Router([options]):创建一个新的路由实例。options可以是一个包含配置选项的对象,例如设置路由前缀prefix等。
  • router.get(path, [middleware,...], callback):定义处理 GET 请求的路由。
  • router.post(path, [middleware,...], callback):定义处理 POST 请求的路由。
  • router.put(path, [middleware,...], callback):定义处理 PUT 请求的路由。
  • router.delete(path, [middleware,...], callback):定义处理 DELETE 请求的路由。
  • router.patch(path, [middleware,...], callback):定义处理 PATCH 请求的路由。
router.get('/users', async (ctx, next) => {
  ctx.body = 'Get all users';
});
  • router.all(path, [middleware,...], callback):定义处理所有 HTTP 方法的路由。
router.all('/admin', async (ctx, next) => {
  if (ctx.request.method === 'GET') {
    ctx.body = 'Admin page';
  } else {
    ctx.body = 'Not allowed';
  }
});
  • 在路径中使用冒号:来定义路由参数。可以通过ctx.params获取参数值。
// 带参数的路由
router.get('/users/:id', async (ctx, next) => {
  const userId = ctx.params.id;
  ctx.body = `User with id ${userId}`;
});
  • 命名路由router.url(name, [params], [query]):根据路由名称生成 URL。需要先给路由命名才能使用这个方法。
router.get('/login', async (ctx, next) => {
  ctx.body = 'Login page';
}).name('login');

const loginUrl = router.url('login');
console.log(loginUrl);
  • router.allowedMethods():这个方法应该在所有路由定义之后添加,用于处理不支持的 HTTP 方法和发送适当的响应头。
// app 是 Koa 实例
app.use(router.routes());
app.use(router.allowedMethods());

使用示例

创建router/userRouter.js

// 引入路由,Router是一个类
const Router = require('koa-router');
// 创建一个路由实例 userRouter,并设置了一个前缀为 /user。
// 这意味着所有定义在这个路由实例上的路径都会自动加上这个前缀。
const userRouter = new Router({prefix: '/user'});

// 创建路由组来组织相关的路由
userRouter.get('/list', async (ctx, next) => {
  // 因为有前缀,实际访问的路径是 /userlist
  // 处理 GET 请求
  ctx.body = 'The URL for this page is /user/list';
});

module.exports = userRouter

main.js 中引入并使用路由userRouter

const Koa = require('koa');
const { APP_PORT } = require('./config/config.env');
const userRouter = require('./router/userRoute')

// 创建koa实例对象:app
const app = new Koa();

// 注册中间件,注意:app.use 必须接收函数作为中间件
app.use(userRouter.routes())

app.use((ctx, next) => {
  // 中间件逻辑
  ctx.body = 'hello Koa!';
});

app.listen(APP_PORT, () => {
  console.log(`server is running on http://localhost:${APP_PORT}`);
});

现在,项目目录结构如下:
在这里插入图片描述

项目结构优化

把http服务与app业务拆分

  1. 把业务代码从入口文件 main.js 中拆分出来,放到 src/app/index.js 中:
const Koa = require('koa');

const userRouter = require('../router/userRoute')

// 创建koa实例对象:app
const app = new Koa();

// 注册中间件,注意:app.use 必须接收函数作为中间件
app.use(userRouter.routes())

module.exports = app
  1. 改写 main.js
// 读取配置文件
const { APP_PORT } = require('./config/config.env');
// 加载 app 模块
const app = require('./app/index')
// app 模块启动 http server
app.listen(APP_PORT, () => {
  console.log(`server is running on http://localhost:${APP_PORT}`);
});

将路由和控制器拆分

路由:解析URL,分发给控制器对应的方法
控制器:处理不同的业务

示例

创建controller/userController.js

class userController {
  async register(ctx, next) {
    ctx.body = '用户注册成功'
  }

  async login(ctx, next) {
    ctx.body = '用户登录成功'
  }
}

// 导出userController的实例(new userController()是一个对象)
module.exports = new userController()

改写router/userRoute.js

// 引入路由,Router是一个类
const Router = require('koa-router');

// 通过解构的方式引入控制器方法
const { register, login } = require('../controller/userController')

const userRoute = new Router({prefix: '/user'});

// 注册接口
userRoute.post('/register', register);

// 登录
userRoute.post('/login', login);

module.exports = userRoute

浏览器默认发送的请求都是get请求,如果要发送post请求,可以使用postman
使用 postman 测试接口:
在这里插入图片描述在这里插入图片描述
现在,项目目录结构如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2191140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1C++入门基础(一)

文章目录 什么是C?C的发展史C关键字(C98)命名空间命名空间的定义命名空间的使用 C中的输入和输出缺省参数缺省参数的概念缺省参数分类全缺省参数半缺省参数 函数重载函数重载的概念函数重载的原理(名字修饰) extern#1. 符号的声明与定义#1.1 变量的声明与定义#1.2 函数的声明和…

均值模板和二阶差分模板的频率响应

均值模板和二阶差分模板都是偶对称。实偶函数的傅里叶变换仍是实偶函数。 给个证明过程 实偶函数 一个函数 f ( x ) f(x) f(x) 被称为实偶函数,如果它满足以下条件: f ( − x ) f ( x ) f(-x) f(x) f(−x)f(x) 傅里叶变换 对于一个实偶函数 f (…

实验 | 使用本地大模型从论文PDF中提取结构化信息

非结构文本、图片、视频等数据是待挖掘的数据矿藏, 在经管、社科等研究领域中谁拥有了_从非结构提取结构化信息的能力_,谁就拥有科研上的数据优势。正则表达式是一种强大的文档解析工具,但它们常常难以应对现实世界文档的复杂性和多变性。而随…

【Codeforces】CF 2007 E

E. Iris and the Tree #树形结构 #贪心 #数学 题目描述 Given a rooted tree with the root at vertex 1 1 1. For any vertex i i i ( 1 ≤ i ≤ n 1 \leq i \leq n 1≤i≤n) in the tree, there is an edge connecting vertices i i i and p i p_i pi​ ( 1 ≤ p i ≤…

Python使用matplotlib绘制图形大全(曲线图、条形图、饼图等)

matplotlib 的主要组成部分是 pyplot,它是一个类似于 MATLAB 的绘图框架。pyplot 提供了一个 MATLAB 式的接口,可以隐式地创建图形和轴,使得绘图变得简单。 以下是一个简单的 matplotlib 使用示例,用于绘制一条简单的折线图&…

Linux:进程间通信之信号量

system V的进程间通信除了共享内存,还有消息队列和信号量 IPC(进程间通信的简称) 消息队列 消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法 每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同…

Electron 使⽤ electron-builder 打包应用

electron有几种打包方式,我使用的是electron-builder。虽然下载依赖的时候让我暴躁,使用起来也很繁琐,但是它能进行很多自定义,打包完成后的体积也要小一些。 安装electron-builder: npm install electron-builder -…

cherry-markdown开源markdown组件详细使用教程

文章目录 前言开发定位目标调研技术方案前提工作量安排数据库表设计实现步骤1、引入依赖2、实现cherry-markdown的vue组件(修改上传接口路径)3、支持draw.io组件4、支持展示悬浮目录toc前端使用:编辑状态使用cherry-markdown的vue组件前端使用…

图像转3D视差视频:DepthFlow

参看: https://github.com/BrokenSource/DepthFlow 通过深度图实现图像3d效果 安装 https://brokensrc.dev/get/pypi/#installing pip insatll depthflow shaderflow broken-source pianola spectronote turbopipe 使用 1、下载项目 git clone https://github.com/BrokenS…

巧用armbian定时任务控制开发板LED的亮灭

新买了个瑞莎 3E 开发板,号称最小SBC,到了之后简直玩开了花,各种折腾后 安装好armbian系统,各种调优。 不太满意的地方:由于太小的原因,导致两个USBTYPEC的接口距离很近,所以买的OTG转接口如果有点宽的话 会显得特别拥挤。 还有就是每天晚上天黑了之后,卧室里的…

大数据处理从零开始————4.认识HDFS分布式文件系统

1.分布式文件系统HDFS 1.1 认识HDFS 当单台服务器的存储容量和计算性能已经无法处理大文件时,分布式文件系统应运而生。什么是分布式系统,分布式系统是由多个独立的计算机或节点组成的系统,这些计算机通过网络连接&#xff…

Map: 地图

对全国2023年各省市的人口分布情况,做出地图展示效果 参考:Map - Map_base - Document (pyecharts.org) 1、模板 # -*- coding: gbk -*- from pyecharts import options as opts from pyecharts.charts import Map from pyecharts.faker import Faker…

如何安全地大规模部署 GenAI 应用程序

大型语言模型和其他形式的生成式人工智能(GenAI) 的广泛使用带来了许多组织可能没有意识到的安全风险。幸运的是,网络和安全提供商正在寻找方法来应对这些前所未有的威胁。 随着人工智能越来越深入地融入日常业务流程,它面临着泄露专有信息、提供错误答…

交换排序:冒泡排序、递归实现快速排序

目录 冒泡排序 1.冒泡排序的核心思想 2.冒泡排序的思路步骤 3.冒泡排序代码 4.代码分析 5.对冒泡排序的时间复杂度是O(N^2)进行解析 6.冒泡排序的特性总结 递归实现快速排序(二路划分版本) 1.快速排序基本思路 2.代码思路步骤 3.代码实现 4.代码分析 (1)递归终止条…

队列的实现与讲解

一.概念与结构 1.概念 只允许在⼀端进行插⼊数据操作,在另⼀端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) ​ 入队列:进⾏插⼊操作的⼀端称为队尾 ​ 出队列:进⾏删除操作的⼀端称为队头 注意&…

美联储巨亏背后的秘密

听说美联储报告称亏损已破2000亿美元,这一数字无疑触动了市场的敏感神经。 亏损的直接原因是美联储在加息周期期间,为了维持短期利率在目标水平,向金融机构支付的利息超过了其持有债券的利息收入。 然而,美联储官员强调&#xff…

学习C语言(23)

整理今天的学习内容 1.文件的概念 使用文件是为了将数据永久化地保存 按照文件功能,在程序设计中一般把文件分成两类: 每个文件都有一个唯一的文字标识,文字标识常被称为文件名,文件名包含文件路径,文件名主干和文件…

如何快速切换电脑的ip地址

在当今的数字化时代,IP地址作为网络身份的重要标识,其重要性日益凸显。无论是出于保护个人隐私的需要,还是为了访问特定的网络服务等,快速切换电脑的IP地址已成为许多用户的迫切需求。本文将为你介绍几种实用的方法,帮…

【Hadoop】改一下core-site.xml和hdfs-site.xml配置就可以访问Web UI

core-site.xml: hdfs-site.xml: 所有的都改为0.0.0.0 就可以访问Web UI 原因: 使用 0.0.0.0 作为绑定地址时,实际会将服务监听在所有可用的网络接口上。这意味着,任何从外部访问的请求都可以通过任何网络适配器连接到…

黑神话:仙童,数据库自动反射魔法棒

黑神话:仙童,数据库自动反射魔法棒 Golang 通用代码生成器仙童发布了最新版本电音仙女尝鲜版十一及其介绍视频,视频请见:https://www.bilibili.com/video/BV1ET4wecEBk/ 此视频介绍了使用最新版的仙童代码生成器,将 …