【KOA框架】koa框架基础及swagger接口文档搭建

koa是express的一层封装,语法比express更加简洁。所以有必要了解下koa的相关开发方法。
在这里插入图片描述

代码实现

  • package.json
{"name": "koapp","version": "1.0.0","main": "index.js","scripts": {"dev": "npx nodemon src/app.js"},"keywords": [],"author": "","license": "ISC","description": "","dependencies": {"jsonwebtoken": "^9.0.2","koa": "^2.15.3","koa-bodyparser": "^4.4.1","koa-jwt": "^4.0.4","koa-router": "^13.0.1","koa2-swagger-ui": "^5.11.0","mysql": "^2.18.1","swagger-jsdoc": "^6.2.8"}
}
  • 入口文件app.js
const Koa = require("koa");
const logger = require("./mid/logger");
const hello = require("./mid/hello");
const userRouter = require("./router/user");
const publicRouter = require("./router/public");
const sysRouter = require("./router/sys");
const bodyParser = require("koa-bodyparser");
const handlerError = require("./mid/errorHandle");
const Result = require("./utils/result");const jwt = require("koa-jwt");
const secret = "zhangsanfeng";const app = new Koa();
app.use(handlerError);// 中间件 自定义了 401 响应,将用户验证失败的相关信息返回给浏览器
app.use(function (ctx, next) {return next().catch((err) => {if (401 == err.status) {ctx.status = 401;ctx.body = Result.error(401, "无效的token");} else {throw err;}});
});app.use(jwt({secret,// passthrough: true,// cookie: "token", // 从 cookie 中获取tokendebugger: true,}).unless({ path: [/^\/public/, /^\/sys\/login/] })
);// 注册路由中间件
app.use(bodyParser());app.use(userRouter.routes()).use(userRouter.allowedMethods());
app.use(publicRouter.routes()).use(publicRouter.allowedMethods());
app.use(sysRouter.routes()).use(sysRouter.allowedMethods());// 全局异常处理;
app.on("error", (error, ctx) => {console.log("ssss", error.status);
});app.listen(3000);
  • 错误中间件
const Result = require("../utils/result");async function handlerError(ctx, next) {try {await next(); // 执行后代的代码if (!ctx.body) {// 没有资源ctx.status = 404;// ctx.body = "404";}} catch (error) {// 如果后面的代码报错 返回500ctx.status = error.status;if (error.status == 404) {ctx.body = Result.error("找不到资源");} else if (error.status == 500) {console.log("🚀 ~ app.on ~ error.status:", error.status);ctx.body = Result.error("服务器异常,请稍后再试");} else if (error.status === 401) {ctx.body = Result.error("未授权 " + error.message);} else {ctx.body = Result.error("未知错误");}// ctx.body = "500";}
}module.exports = handlerError;
  • 日志中间件
async function logger(ctx, next) {console.log("logger before...");await next();const rt = await ctx.response.get("X-Response-Time");console.log(`${ctx.method} ${ctx.url} - ${rt}`);console.log(ctx.username, "from mid");console.log("logger after...");
}
module.exports = logger;
  • 路由

不需要拦截的路由

const Router = require("koa-router");
const router = new Router();router.prefix("/public");router.get("/", async (ctx) => {console.log("🚀 ~ router.get ~ ctx:", ctx.params);ctx.body = {id: ctx.params.id,name: "小明1111",age: 18,sex: "男",};// ctx.throw(401);
});router.get("/:id", async (ctx) => {console.log("🚀 ~ router.get ~ ctx:", ctx.params);ctx.body = {id: ctx.params.id,name: "小明",age: 18,sex: "男",};// ctx.throw(401);
});module.exports = router;
  • 登录获取token的路由
const Router = require("koa-router");
const router = new Router();
const jwt = require("koa-jwt");
const { sign } = require("jsonwebtoken");
const Result = require("../utils/result");
const secret = "zhangsanfeng";router.prefix("/sys");router.post("/login", async (ctx, next) => {const body = ctx.request.body;if (body.username !== "zhangsan" || body.pwd !== "123456") {ctx.body = Result.error("账号或密码错误");// ctx.throw(401, "账号或密码错误");} else {const token = sign({ abcsd: "aaaaaa" }, secret, { expiresIn: "1h" });ctx.body = Result.success({ token });}
});router.get("/userInfo", async (ctx, next) => {ctx.body = {name: "zhangsanfeng",age: 20,sex: "男",};
});router.get("/logout", async (ctx, next) => {ctx.body = Result.success("退出成功");ctx.cookies.set("token", "", { signed: false, maxAge: 0 });
});module.exports = router;
  • 用户路由
const Router = require("koa-router");
const router = new Router();router.prefix("/user/s");router.get("/:id", async (ctx) => {console.log("🚀 ~ router.get ~ ctx:", ctx.params);ctx.body = {id: ctx.params.id,name: "小明2222",age: 18,sex: "男",};// ctx.throw(401);
});router.get("/", async (ctx) => {console.log("🚀 ~ router.get ~ ctx:", ctx.query);ctx.body = {id: ctx.params.id,name: "小明3333",age: 18,sex: "男",};
});router.post("/", async (ctx) => {console.log("🚀 ~ router.get ~ ctx:", ctx.request.body);ctx.body = {id: ctx.params.id,name: "小明4444",age: 18,sex: "男",};
});module.exports = router;
  • 工具方法
class Result {constructor(message, code, data) {this.message = message;this.code = code;this.data = data;}static success() {return new Result("success", 0, null);}static success(data) {return new Result("success", 0, data);}static error(message) {return new Result(message, null, 1);}
}module.exports = Result;

实现效果

  • 未登录获取列表信息
    在这里插入图片描述

  • 登录账号或密码错误

在这里插入图片描述

  • 登录成功
    在这里插入图片描述
  • 获取用户信息成功
    在这里插入图片描述

swagger文档配置

  • 配置参考文档:https://swagger.io/docs/specification/v3_0/paths-and-operations/
  • post接口文档的书写
const Router = require("koa-router");
const router = new Router();
const jwt = require("koa-jwt");
const { sign } = require("jsonwebtoken");
const Result = require("../utils/result");
const secret = "zhangsanfeng";
const mysql = require("../mysql");router.prefix("/sys");/*** @swagger* tags:*   name: Users*   description: User management*//*** @swagger* components:*   schemas:*     User:*       type: object*       properties:*         username:*           type: string*           description: username.*         password:*           type: string*           description: password.*       required:*         - username*         - password*//*** @swagger* /sys/login:*   post:*     summary: login system.*     tags: [Users]*     requestBody:*       description: Optional description in *Markdown**       required: true*       content:*         application/json:*           schema:*             type: object*             properties:*               username:*                 type: string*                 example: zhangsan*               pwd:*                 type: string*                 example: 123456*     description: User login system.*     responses:*       200:*         description: user login system.*         content:*           application/json:*             schema:*               type: array*               items:*                 $ref: '#/components/schemas/User'*/
router.post("/login", async (ctx, next) => {const body = ctx.request.body;if (body.username !== "zhangsan" || body.pwd !== "123456") {ctx.body = Result.error("账号或密码错误");// ctx.throw(401, "账号或密码错误");} else {const token = sign({ abcsd: "aaaaaa" }, secret, { expiresIn: "1h" });ctx.body = Result.success({ token });}
});router.get("/userInfo", async (ctx, next) => {const id = 2;// 查询数据库mysql.query("select * from tb_user where id = ?", [id], (err, result) => {console.log("🚀 ~ mysql.query ~ result:", result);if (err) {ctx.body = Result.error("查询失败");} else {ctx.body = Result.success(result[0]);}});ctx.body = {name: "zhangsanfeng",age: 20,sex: "男",};
});router.get("/logout", async (ctx, next) => {ctx.body = Result.success("退出成功");ctx.cookies.set("token", "", { signed: false, maxAge: 0 });
});module.exports = router;
  • 全局配置swaager
const Router = require("koa-router");
const router = new Router();
const swaggerJSdoc = require("swagger-jsdoc");
const path = require("path");const swaggerDefinition = {openapi: "3.0.0",info: {title: "koa2搭建的app项目接口API",version: "1.0.0",description: "测试项目的接口文档",},host: "localhost:8080",basePath: "/",
};const options = {swaggerDefinition,apis: [path.join(__dirname, "../router/*.js")],
};const swaggerSpec = swaggerJSdoc(options);router.get("/swagger.json", (ctx) => {ctx.set("Content-Type", "application/json");ctx.body = swaggerSpec;
});module.exports = router;
  • 入口文件配置swagger
const Koa = require("koa");
const { koaSwagger } = require("koa2-swagger-ui");
console.log("🚀 ~ koaSwagger:", koaSwagger);const logger = require("./mid/logger");
const hello = require("./mid/hello");
const userRouter = require("./router/user");
const publicRouter = require("./router/public");
const sysRouter = require("./router/sys");
const bodyParser = require("koa-bodyparser");
const handlerError = require("./mid/errorHandle");
const Result = require("./utils/result");
const swagger = require("./utils/swagger");const jwt = require("koa-jwt");
const secret = "zhangsanfeng";// 数据库连接
const mysql = require("./mysql/index");
mysql.connect();const app = new Koa();
app.use(handlerError);// 中间件 自定义了 401 响应,将用户验证失败的相关信息返回给浏览器
app.use(function (ctx, next) {return next().catch((err) => {if (401 == err.status) {ctx.status = 401;ctx.body = Result.error(401, "无效的token");} else {throw err;}});
});app.use(jwt({secret,// passthrough: true,// cookie: "token", // 从 cookie 中获取tokendebugger: true,}).unless({path: [/^\/public/, /^\/sys\/login/, /^\/swagger/, /^\/apidocs/],})
);// 注册路由中间件
app.use(bodyParser());app.use(userRouter.routes()).use(userRouter.allowedMethods());
app.use(publicRouter.routes()).use(publicRouter.allowedMethods());
app.use(sysRouter.routes()).use(sysRouter.allowedMethods());
app.use(swagger.routes()).use(swagger.allowedMethods());app.use(koaSwagger({routePrefix: "/swagger",swaggerOptions: {url: "/swagger.json",},})
);// 全局异常处理;
app.on("error", (error, ctx) => {console.log("ssss", error.status);
});app.listen(3000);

效果测试

测试登录成功

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[深度学习]机器学习和深度学习

机器学习和深度学习 文章目录 机器学习和深度学习人工智能与机器学习和深度学习的关系侠义的机器学习深度学习的概念常见的神经网络的输入形式想要的输出(任务类别)深度学习的流程 线性函数与多层神经元 人工智能与机器学习和深度学习的关系 所谓人工智能就是,让计算…

【QT】已解决:Qt4.11.0无法使用MSVC编译器问题

目录 一、背景 1.本机环境 2.问题描述 3.问题解决前后对比图 二、详细操作 1.下载项目二所需qt环境 2.解决思路 3.安装VS2017 4.安装MSVC调试器 5.打开qtCreator查看编译器 5.编译运行项目二 三、参考 一、背景 1.本机环境 windows11 qtCreator4.11.0 minGW 64位…

C++ 模拟真人鼠标轨迹算法 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序,它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言,原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势: 模拟…

从零开始:Spring Boot核心概念与架构解析

引言 在当今的Java开发领域,Spring Boot已经成为构建企业级应用的首选框架之一。它以其简洁、高效、易于上手的特点,极大地简化了Spring应用的开发过程。本文将从Spring Boot的核心概念入手,深入解析其架构设计和运行原理,帮助读…

【EdgeAI实战】(1)STM32 边缘 AI 生态系统

【EdgeAI实战】(1)STM32 边缘 AI 生态系统 【EdgeAI实战】(1)STM32 边缘 AI 生态系统 1. STM32 边缘人工智能1.1 X-CUBE-AI 扩展包1.2 STM32 AI Model Zoo1.3 ST AIoT Craft 2. STM32N6 AI 生态系统 (STM32N6-AI)2.1 STM32N6 AI 产…

SSE 实践:用 Vue 和 Spring Boot 实现实时数据传输

前言 大家好,我是雪荷。最近我在灵犀 BI 项目中引入了 SSE 技术,以保证图表的实时渲染,当图表渲染完毕服务端推送消息至浏览器端触发重新渲染。 什么是 SSE? SSE 全称为 Server-Send Events 意思是服务端推送事件。 SSE 相比于 …

关于机器学习的一份总结

在之前的文章中分别有详细的关于机器学习中某一学习算法的介绍,但缺少一个总体关于机器学习的总结,所以在这篇文中就是关于机器学习的一份总结。 在最近的日子中,人工智能日益火热起来,而机器学习是其中举足轻重的一部分&#xf…

浅谈计算机网络03 | 现代网络组成

现代网络组成 一 、网络生态体系1.1网络生态系统的多元主体1.2 网络接入设施的多样类型 二、现代网络的典型体系结构解析三、高速网络技术3.1 以太网技术3.2 Wi-Fi技术的深度剖析3.2.1 应用场景的多元覆盖3.2.2 标准升级与性能提升 3.3 4G/5G蜂窝网的技术演进3.3.1 蜂窝技术的代…

数据结构漫游记:队列的动态模拟实现(C语言)

嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的pa…

Ubuntu22.04安装paddle GPU版本

文章目录 确立版本安装CUDA与CUDNN安装paddle 确立版本 查看官网信息,确立服务版本:https://www.paddlepaddle.org.cn/documentation/docs/zh/2.6/install/pip/linux-pip.html 安装CUDA与CUDNN 通过nvidia-smi查看当前显卡驱动版本: 通过…

2024年度总结:从后端Java到全栈成长的蜕变

目录 前言1. 用数据与实践书写成长篇章2. 技术与生活的双重蜕变3. 技术的进阶与生活的绽放 前言 今年是我入行的第十年,也是记录在CSDN平台上的第五年。这五年来,我始终坚持记录成长的点滴,将个人事业与博客创作紧密相连。一路走来&#xff0…

麦田物语学习笔记:创建TransitionManager控制人物场景切换

基本流程 制作场景之间的切换 1.代码思路 (1)为了实现不同场景切换,并且保持当前的persistentScene一直存在,则需要一个Manager去控制场景的加载和卸载,并且在加载每一个场景之后,都要将当前的场景Set Active Scene,保证其为激活的场景,在卸载的时候也可以方便调用当前激活的场…

无人机高速无刷动力电机核心设计技术

一、技术概述 无刷电机优势: 高效率:无刷电机由于去除了电刷和换向器,减少了能量损失,因此具有更高的效率。 长寿命:电刷和换向器的磨损是导致传统有刷电机寿命较短的主要原因,而无刷电机则避免了这一问…

Linux C\C++方式下的文件I/O编程

【图书推荐】《Linux C与C一线开发实践(第2版)》_linux c与c一线开发实践pdf-CSDN博客 《Linux C与C一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 Lin…

python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)角点检测

角点检测(Corner Detection)是计算机视觉和图像处理中重要的步骤,主要用于提取图像中的关键特征,以便进行后续的任务,比如图像匹配、物体识别、运动跟踪等。下面介绍几种常用的角点检测方法及其应用。 1. Harris角点检…

QT开发-T113 Linux 主板QC配置套件

此篇文章用于记录在Linux主板上使用QT开发项目的套件配置步骤 进入QC软件,点击 Manage Kits… 选择项目对应的QT Version : 一般有一个项目对应的qmake 文件,选择导入即可 如果首次导入提示 qmake could not be added 需要先对项目进行命令行编译(具体命…

【云岚到家】-day03-门户缓存实现实战

【云岚到家】-day03-门户缓存实现实战 1.定时任务更新缓存 1.1 搭建XXL-JOB环境 1.1.1 分布式调度平台XXL-JOB介绍 对于开通区域列表的缓存数据需要由定时任务每天凌晨更新缓存,如何实现定时任务呢? 1.使用jdk提供的Timer定时器 示例代码如下&#xf…

SuperdEye:一款基于纯Go实现的间接系统调用执行工具

关于SuperdEye SuperdEye是一款基于纯Go实现的间接系统调用执行工具,该工具是TartarusGate 的修订版,可以利用Go来实现TartarusGate 方法进行间接系统调用。 该工具的目标是为了扫描挂钩的NTDLL并检索Syscall编号,然后使用它来执行间接系统调…

Python+ tkinter实现小学整数乘法和除法竖式演算式

Python tkinter实现小学整数乘法和除法竖式演算式 整数的乘法与除法是小学数学中的重要内容,它们是数学运算中的基础部分。 本文将使用python 和Python 的标准 GUI(图形用户界面)包tkinter,实现整数乘法与除法的竖式演示。供有兴趣…

线程池遇到未处理的异常会崩溃吗?

线程池中的 execute 和 submit 方法详解 目录 引言execute 方法 使用示例代码 submit 方法 2.1 提交 Callable 任务2.2 提交 Runnable 任务 遇到未处理异常 3.1 execute 方法遇到未处理异常3.2 submit 方法遇到未处理异常 小结 引言 在多线程编程中,线程池是提高性…