Koa2项目实战2(路由管理、项目结构优化)
添加路由(处理不同的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业务拆分
- 把业务代码从入口文件
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
- 改写
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
测试接口:
现在,项目目录结构如下:
相关文章:

Koa2项目实战2(路由管理、项目结构优化)
添加路由(处理不同的URL请求) 路由:根据不同的URL,调用对应的处理函数。 每一个接口服务,最核心的功能是:根据不同的URL请求,返回不同的数据。也就是调用不同的接口返回不同的数据。 在 Node…...

决战Linux操作系统
前言: 你是否也曾经为Linux所困扰过,在网上找的资料零零散散,是否学完Linux后还是懵懵懂懂,别怕,这篇博客是博主精心为你准备的,现在,就让我们一起来走进Linux的世界,决战Linux&…...
OceanBase 3.2.2 数据库问题处理记录
只记录OceanBase 数据库与OCP的异常处理,其它组件暂时不写录。 一、问题1: 说明:OMS 出现异常,无法访问(OB无法访问) OB数据库架构:1:1:1 原因:某一台OBserver因为内存问题,被服务器直接kill掉…...

HCIP--以太网交换安全(二)端口安全
端口安全 一、端口安全概述 1.1、端口安全概述:端口安全是一种网络设备防护措施,通过将接口学习的MAC地址设为安全地址防止非法用户通信。 1.2、端口安全原理: 类型 定义 特点 安全动态MAC地址 使能端口而未是能Stichy MAC功能是转换的…...

在 Windows 11 安卓子系统中安装 APK 的操作指南
这个软件好像不可以在纯android系统中使用(不知道是缺了什么),其他对于android的虚拟机要不缺少必要功能组件,要不性能过于低下。本方法致力于在带有谷歌框架WSA中运行该APK 在 Windows 11 安卓子系统中安装 APK 的操作指南 本指…...

[C语言] 函数详解:库函数与自定义函数
文章目录 函数的概念库函数和自定义函数库函数使用库函数示例常用库函数及头文件 自定义函数自定义函数的基本结构示例:实现两个数的求和函数自定义函数的好处 函数的返回值有返回值的函数无返回值的函数 函数的声明与调用声明函数在另一个文件中调用函数示例&#…...
0x11 科迈 RAS系统 Cookie验证越权漏洞
参考: 科迈 RAS系统 Cookie验证越权漏洞 | PeiQi文库 (wgpsec.org)免责声明 欢迎访问我的博客。以下内容仅供教育和信息用途: 合法性:我不支持或鼓励非法活动。请确保遵守法律法规。信息准确性:尽管我尽力提供准确的信息,但不保证其完全准确或适用。使用前请自行验证。风…...

MoonBit 双周报 Vol.57:AI助手功能增强、表达式优先级调整、JS 交互优化、标准库与实验库API多项更新!
2024-10-08 IDE更新 AI Codelens支持 /generate 和 /fix 命令 /generate 命令能够提供一个通用的用以生成代码的聊天界面。 /fix 命令能够读取当前函数的错误信息给出修复建议。 MoonBit更新 调整中缀表达式和if、match、loop、while、for、try表达式的优先级, 后者这些控制…...
element ui input textarea控制显示高度
样式代码 .testPage { position: absolute; left: 0; top: 0; right: 0; bottom: 0; display: flex; height: 100%; /* 控制输入框高度 */ .el-textarea { height: 90%; ::v-deep .el-textarea__inner { height: 90%; } } }...
Chromium 中chrome.downloads扩展接口c++
一、前端chrome.downloads 使用 chrome.downloads API 以编程方式启动、监控、操作和搜索下载内容。 权限 downloads 您必须在扩展程序清单中声明 "downloads" 权限,才能使用此 API。 {"name": "My extension",..."permiss…...
微信小程序常见问题
一、编译报错 [ app.json 文件内容错误] app.json: 在项目根目录未找到 app.json 解决办法: 微信开发者工具中打开设置->安全设置->打开服务端口用HBuilder X打开小程序文件夹,点击“运行到小程序模拟器”,生成配置文件,…...

进程的理解
进程的理解 目录: 什么是进程主要特征主要组成部分进程状态进程优先级 1.什么是进程 概念: 在操作系统中,**进程(Process)**是一个正在执行的程序实例。可以将进程理解为一个动态的实体,它不仅包括静态…...
LeetCode494:目标和
题目链接:494. 目标和 - 力扣(LeetCode) 代码如下 class Solution { public:int findTargetSumWays(vector<int>& nums, int target) {int sum 0;for(int i 0; i < nums.size(); i){sum nums[i];}if(abs(target) > sum)…...
vue3中自定义校验函数密码不生效问题
vue3中自定义校验函数密码不生效问题 由于在自定义的校验规则中只校验了有数据的情况,以至于在没输入时,校验不生效 (1)用户不输入校验不生效 const validateSurePassword (rule, value, callback) > {if (value ! ) {if (…...

RabbitMQ(死信队列)
一、本文抒写背景 前面我也在延迟队列篇章提到过死信队列,也提到过一些应用场景! 今天呢,这篇文章,主要就是实战一个业务场景的小Demo流程,哈哈,那就是延迟关闭订单。 二、开始啦!letgo! 首…...

HTTP代理的优点和局限性
在这个信息爆炸的时代,网络已成为我们获取知识、交流思想、开展商务的重要平台。但随之而来的隐私泄露、网络安全威胁、以及无处不在的网络监控,却让我们的每一次在线活动都充满了风险。 在这样的背景下,HTTP代理技术应运而生,它不…...
大厂面试真题-如果通过JVM自带的工具排查和解决线上CPU100%的问题
通过JVM自带的工具去定位和解决线上CPU 100%的问题,可以遵循以下步骤: 一、使用top和jps定位Java进程 使用top命令: 在Linux服务器上执行top命令,查看所有进程的CPU使用情况。找到CPU使用率最高的进程,并记录其PID&a…...

kubernetes中微服务部署
微服务 问:用控制器来完成集群的工作负载,那么应用如何暴漏出去? 答:需要通过微服务暴漏出去后才能被访问 Service 是一组提供相同服务的Pod对外开放的接口借助Service,应用可以实现服务发现和负载均衡Service 默认只…...
基于 Java 的天气预报系统设计与实现
随着互联网的飞速发展,天气预报系统变得越来越重要。它可以帮助用户了解未来几天的天气情况,便于出行、活动安排。本文将介绍如何使用 Java 构建一个简单的天气预报系统,涉及系统架构设计、核心功能开发以及完整的代码实现。 1. 系统架构设计…...
思迅商云8前台打开提示上传日志信息失败
请按照以下步骤核实处理: 1、重启sql服务后测试。 2、请先备份前台安装目录,之后删除安装目录下的log文件和localdate下的log文件,之后重新打开软件,若依旧不行则说明前台文件有损坏,需要重新安装客户端,…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡
何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践,很多人以为AI已经强大到不需要程序员了,其实不是,AI更加需要程序员,普通人…...