目录
前言:
准备工作:
前端代码:
后端目录截图:
1.获取参数
2.校验参数
3.查询数据库中是否已经存在该用户
4.用户入库
5.测试一哈
添加用户成功
同样的用户名再注册一遍
编辑总结:
前言:
在阅读这篇文章之前,想必已经对Egg有了初步的了解,至于如何创建一个egg项目之类的,配置mysql数据库之类的等等这里就不再赘述,不知道的可以去egg官方了解--Egg官方文档;
本文着重记录在Egg中如何使用Joi进行参数的校验,以及一个小型的用户注册接口开发!本人也不经常写node,所以代码不是很标准可能,还请各位多多包涵!
准备工作:
先说说我设计的用户注册流程,很简单,一个用户名username,一个密码password。使用的uniapp运行到了h5,长下面这个样子。
因为重点在于后端,所以在前端字段将不会做任何的校验,点击注册按钮请求我们写的接口即可,后端流程大概分以下几步!
- 拿到前端请求参数,进行参数校验,使参数符合我们的校验规则即可!
- 校验通过后,通过用户名username进行数据查询,不允许有重复的用户名存在!
- 用户名没有任何问题后,对password进行加密处理!
- 存入数据库,返回给前端响应内容!

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













![Mysql问题:[Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause](https://img-blog.csdnimg.cn/1066a58e1b5d4b119df843e604651406.png)






