当前位置: 首页 > news >正文

Egg:使用joi进行参数校验以及注册接口小demo

目录

前言:

准备工作:

前端代码:

后端目录截图:

1.获取参数

2.校验参数

3.查询数据库中是否已经存在该用户

4.用户入库

5.测试一哈

添加用户成功

 同样的用户名再注册一遍

​编辑总结:


前言:

        在阅读这篇文章之前,想必已经对Egg有了初步的了解,至于如何创建一个egg项目之类的,配置mysql数据库之类的等等这里就不再赘述,不知道的可以去egg官方了解--Egg官方文档;

        本文着重记录在Egg中如何使用Joi进行参数的校验,以及一个小型的用户注册接口开发!本人也不经常写node,所以代码不是很标准可能,还请各位多多包涵!

准备工作:

        先说说我设计的用户注册流程,很简单,一个用户名username,一个密码password。使用的uniapp运行到了h5,长下面这个样子。

        因为重点在于后端,所以在前端字段将不会做任何的校验,点击注册按钮请求我们写的接口即可,后端流程大概分以下几步!

  1. 拿到前端请求参数,进行参数校验,使参数符合我们的校验规则即可!
  2. 校验通过后,通过用户名username进行数据查询,不允许有重复的用户名存在!
  3. 用户名没有任何问题后,对password进行加密处理!
  4. 存入数据库,返回给前端响应内容!

前端代码:

<template><view class="register"><view class="input">username:<input type="text" v-model="user.username"></view><view class="input">password:<input type="text" v-model="user.password"></view><view class=""><button @click="formSubmit">注册</button></view></view>
</template><script setup>import { reactive } from 'vue';const user = reactive({username: '',password: ''})const formSubmit = () => {uni.request({url: "http://127.0.0.1:7001/api/user/register",method: "POST",data: user,success: (res) => {console.log(res);},fail: (err) => {console.log(err);}})};
</script><style lang="scss" scoped>.register {padding: 100rpx 0;width: 700rpx;margin: 0 auto;}.input {margin-bottom: 30rpx;input {border: solid 1px #cecece;height: 60rpx;padding: 0 20rpx;}}
</style>

后端目录截图:

着重关注我圈起来的目录文件

 

 app/extend/context.js:

这个相当于是对返回内容的一个小型封装,可以使用this.ctx访问到。

module.exports = {sendSuccess({ code = 200, data = {}, msg = "ok" }) {this.body = { code, data, msg };},sendFail({ code = 400, data = {}, msg = "fail" }) {this.body = { code, data, msg };},
};

1.获取参数

我们首先需要在app/controller下新建user.js,写入以下内容!

"use strict";const { Controller } = require("egg");class userController extends Controller {/* 用户注册 */async register() {const { ctx, service } = this;const { body } = ctx.request;console.log(body);ctx.sendSuccess({ msg: "egg进行中" });}
}module.exports = userController;

而后在app/router 新建user.js

module.exports = (app) => {const { router, controller } = app;router.post("/api/user/register", controller.user.register);
};

最后在app/router.js中写入如下内容

"use strict";module.exports = (app) => {require("./router/user")(app);
};

 可以看到,我们已经可以获取到前端传递的参数了

2.校验参数

我们在 app/rules 下新建 user.js

首先需要安装Joi,npm install joi 即可!joi文档

const Joi = require("joi");/* 验证注册信息 */
async function registerValidate(params) {const registerSchema = Joi.object({username: Joi.string().min(1).max(10).required().messages({"string.empty": "用户名不能为空","any.required": "用户名必填","string.max": "用户名长度不能超过10",}),password: Joi.string().min(6).max(12).pattern(new RegExp("^[a-zA-Z0-9]{6,12}$")).required().messages({"string.empty": "密码不能为空","any.required": "密码必填","string.min": "密码长度不低于6","string.max": "密码长度不能超过12","string.pattern.base": "密码只能包含大小写字母以及数字",}),});try {await registerSchema.validateAsync(params);} catch (error) {return error.message ?? "参数错误";}
}module.exports = { registerValidate };

要是问我为什么不用官方推荐的 egg-validate,理由就是用不熟,自定义错误信息很难受,我更喜欢joi!

这样的话,我们就可以在 app/controller/user.js 中引入使用

"use strict";const { Controller } = require("egg");
const validate = require("../rules/user");class userController extends Controller {/* 用户注册 */async register() {const { ctx, service } = this;const { body } = ctx.request;/* 用户字段验证 */const validateResult = await validate.registerValidate(body);if (validateResult) {ctx.sendFail({ msg: validateResult });return;}ctx.sendSuccess({ msg: "egg进行中" });}
}module.exports = userController;

测试一下:

当我不输入用户名

用户名长度大于10

密码不填写

密码填写不符合正则表达式

 

等等还有一些别的规则,自己尝试吧!

3.查询数据库中是否已经存在该用户

去到我们 app/service/user.js

const { Service } = require("egg");class userService extends Service {/* 添加用户 */async registerUser(params) {const { ctx } = this;const data = await this.app.mysql.get("users", {username: params.username,});if (data) {ctx.sendFail({ msg: "用户名重复,换一个吧" });return;}}
}module.exports = userService;

4.用户入库

依然还是在 app/service/user.js

我们需要执行 npm install bcryptjs 命令,使用bcryptjs的方法对密码进行加密处理

const { Service } = require("egg");
const bcrypt = require("bcryptjs");class userService extends Service {/* 添加用户 */async registerUser(params) {const { ctx } = this;const data = await this.app.mysql.get("users", {username: params.username,});if (data) {ctx.sendFail({ msg: "用户名重复,换一个吧" });return;}/* 密码入库前加密 */params.password = bcrypt.hashSync(params.password, 10);const result = await this.app.mysql.insert("users", params);return result.affectedRows === 1;}
}module.exports = userService;

 我们需要在 app/controller/user.js 接通数据库操作

"use strict";const { Controller } = require("egg");
const validate = require("../rules/user");class userController extends Controller {/* 用户注册 */async register() {const { ctx, service } = this;const { body } = ctx.request;/* 用户字段验证 */const validateResult = await validate.registerValidate(body);if (validateResult) {ctx.sendFail({ msg: validateResult });return;}/* 进行数据库操作 */try {const result = await service.user.registerUser(body);if (result) {ctx.sendSuccess({ msg: "用户添加成功!" });}} catch (error) {ctx.sendFail({ msg: "用户添加失败!" });}}
}module.exports = userController;

5.测试一哈

添加用户成功

 同样的用户名再注册一遍

总结:

用egg写后端服务的感觉还是很不错的,开箱即用,制定了一系列的规则,按照规则进行代码编写即可,而且具有很高的扩展性,确实还不错!

 

相关文章:

Egg:使用joi进行参数校验以及注册接口小demo

目录 前言&#xff1a; 准备工作&#xff1a; 前端代码&#xff1a; 后端目录截图&#xff1a; 1.获取参数 2.校验参数 3.查询数据库中是否已经存在该用户 4.用户入库 5.测试一哈 添加用户成功 同样的用户名再注册一遍 ​编辑总结&#xff1a; 前言&#xff1a; 在阅…...

天梯赛训练L1-016(查验身份证)

目录 1、L1-016 查验身份证 2、如果帮助到大家了&#xff0c;希望大家一键三连&#xff01;&#xff01;&#xff01; 1、L1-016 查验身份证 分数 15 题目通道 一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下&#xff1a; 首…...

技术方案评审

目录 参考一、流程&规范二、评审维度组件选型性能可伸缩性灵活性可扩展性可靠性安全性兼容性弹性处理事务性可测试性可运维性监控三、方案模板背景目标整体架构业务流程接口定义数据库表功能实现测试计划人力排期Check List整体评估<...

Python机器学习库scikit-learn在Anaconda中的配置

本文介绍在Anaconda环境中&#xff0c;安装Python语言scikit-learn模块的方法。 scikit-learn库&#xff08;简称sklearn&#xff09;是一个基于Python语言的机器学习库&#xff0c;提供了各种机器学习算法和相关工具&#xff0c;包括分类、回归、聚类、降维、模型选择和预处理…...

yarn init 没有 ts 类型声明

yarn 版本为 3. 的初始化项目里&#xff0c;我们下载的包会发现没有 ts 类型提示。那么跟着我做这几个命令&#xff0c;就可以轻松搞定&#xff0c;具体原因我就不贴了&#xff0c;如果有兴趣可以评论问这里只写 vscode 没有提示的修复方式yarn add typescript -Dyarn dlx yarn…...

孩子喜欢打人父母要怎么引导?听听专家的小建议

随着人们生活水平的提高。有些孩子被父母宠坏了&#xff0c;不仅脾气暴躁&#xff0c;还喜欢打人。面对这种情况&#xff0c;许多家长会选择暴制暴&#xff0c;导致孩子更崇尚暴力。被打后&#xff0c;孩子不仅没有悔改&#xff0c;而且变得更糟。即使孩子被说服了&#xff0c;…...

Hive中order by,sort by,distribute by,Cluster by

order by 对数据进行全局排序, 只有一个reducer Task, 效率低 mysql中strict模式下, order by必须要有limit, 不然会拒绝执行. 对于分区表, 必须显示指定分区字段查询。 sort by 可以有多个reduce Task(以distribute by后的字段个数为准) 每个reduce Task内部数据有序, 但…...

PyTorch的自动微分(autograd)

PyTorch的自动微分(autograd) 计算图 计算图是用来描述运算的有向无环图 计算图有两个主要元素&#xff1a;结点&#xff08;Node&#xff09;和边&#xff08;Edge&#xff09; 结点表示数据&#xff0c;如向量、矩阵、张量 边表示运算&#xff0c;如加减乘除卷积等 用计算…...

sum-check protocol

sumcheck是一个交互式证明协议&#xff0c;给定域F上的多元多项式g(x1,...,xv)g(x_1,...,x_v)g(x1​,...,xv​)&#xff0c;证明者Prover可以向验证者Verifier证明该多项式ggg的遍历求和值等于公开值HHH&#xff0c;即 H∑b1,b2,...,bv∈{0,1}vg(b1,b2,...,bv)H \sum_{b_1,b_2,…...

数据结构刷题(二十一):131分割回文串、78子集

1.分割回文串题目链接思路&#xff1a;回溯算法的组合方法&#xff08;分割问题类似组合问题&#xff09;。流程图&#xff1a;红色竖杠就是startIndex。 for循环是横向走&#xff0c;递归是纵向走。回溯三部曲&#xff1a;递归函数参数&#xff1a;字符串s和startIndex&#…...

Spring Aop 详解

主要内容&#xff1a; 了解Spring AOP的概念及其术语熟悉Spring AOP的JDK动态代理熟悉Spring AOP的CGLib动态代理掌握基于XML的AOP实现掌握基于注解的AOP实现AOP用官方话来说&#xff1a; AOP即面向切面编程。和OOP&#xff08;面向对象编程&#xff09;不同&#xff0c;AOP主…...

【数据库死锁】线上问题之数据库死锁

原本平静的一天&#xff0c;惊现生产项目瘫痪问题&#xff0c;马上打开日志&#xff0c;发现后台日志提示了多个“com.mysql.cj.jdbc.exceptions.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction” 大概去了解一下这个异常&#x…...

好友管理系统--课后程序(Python程序开发案例教程-黑马程序员编著-第4章-课后作业)

实例3&#xff1a;好友管理系统 如今的社交软件层出不穷&#xff0c;虽然功能千变万化&#xff0c;但都具有好友管理系统的基本功能&#xff0c;包括添加好友、删除好友、备注好友、展示好友等。下面是一个简单的好友管理系统的功能菜单&#xff0c;如图1所示。 图1 好友管理系…...

Redis 集群 Redis Cluster搭建

Redis集群需要至少三个master节点&#xff0c;我们这里搭建三个master节点192.168.20.130&#xff0c;192.168.20.131&#xff0c;192.168.20.132&#xff0c;并且给每个master再搭建一个slave节点&#xff08;一个节点一主一从&#xff0c;通过端口号区分&#xff09;&#xf…...

博客系统(前后端分离版)

博客系统的具体实现 文章目录博客系统的具体实现软件开发的基本流程具体实现的八大功能数据库设计创建数据库操作数据库引入依赖封装DataSource创建实体类将JDBC增删改查封装起来实现博客列表页web.xml的配置文件实现博客系统的展示功能登录功能强制要求用户登录显示用户信息退…...

第十二章 opengl之模型加载(Assimp)

OpenGLAssimp模型加载库构建Assimp网格网格渲染Assimp 我们不太能够对像是房子、汽车或者人形角色这样的复杂形状手工定义所有的顶点、法线和纹理坐标。我们要的是将这些模型(Model)导入(Import)到程序当中。模型通常都由3D艺术家在Blender、3DS Max或者Maya这样的工具中精心制…...

Stable Matching-稳定匹配问题【G-S算法,c++】

Stable Matching-稳定匹配问题【G-S算法&#xff0c;c】题目描述&#xff1a;(Gale-Shapley算法)解题思路一&#xff1a;G-S算法(Gale-Shapley算法)题目描述&#xff1a;(Gale-Shapley算法) Teenagers from the local high school have asked you to help them with the organ…...

TypeScript(四)接口

目录 前言 定义 用法 基本用法 约定规则 属性控制 任意属性 可选属性 只读属性 定义函数 冒号定义 箭头定义 接口类型 函数接口 索引接口 继承接口 类接口 总结 前言 在介绍TS对象类型中&#xff0c;为了让数组每一项更具体&#xff0c;我们使用 string [ ]…...

Python-基础知识

目录 Python 简介 Python 发展历史 Python 特点 Python 标识符 Python 保留字符 行和缩进 多行语句 Python 引号 Python注释 Python 简介 Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性&#xff0c;相比…...

【java基础】集合基础说明

文章目录基本介绍Collection接口Iterator和Iterable接口Map接口关于Iterator接口的一些说明框架中的接口具体集合总结基本介绍 集合就是存储用来存储一系列数据的一种数据结构。在这篇文章中会介绍集合的一些基本概念。 Collection接口 集合的基本接口是Collection接口&…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...