【Express.js】使用zod检验

这篇具有很好参考价值的文章主要介绍了【Express.js】使用zod检验。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用zod检验

上一节我们介绍了 express-validator,本节我们介绍一个更通用的检验工具 Zod

What’s Zod.js?

写前端的同学可能知道Zod,我们在提交表单前需要对数据初步检查,Zod是一个很棒的工具。前端可以偷懒,但后端不能偷懒,Zod也可以用到我们的 express 后端中来,封装一个 Zod 中间件即可

准备工作

用 evp-express-cli 创建一个最简洁的新项目。

了解Zod工作流程

  1. 定义待检验的数据格式
const { z } = requie("zod");

const schema = z.object({
  username: z.string().nonempty("username cannot be empty")
})

这个 schema 就是 Zod 检验一个对象或者变量的检验器,如果检验目标只是一个值,z.string()之类的即可
2. 检验器验证传入
把待检查的数据传递给检验器,有4种:schema.parse(data), schema.parseSync(data), schema.safeParse(data), schema.safeParseSync(data),parse会直接抛出错误信息,而safeParse返回一个对象,包含了验证是否成功和错误信息,结构如是:{success: boolean, message: ZodError}
3. 错误处理
对于检验器发现的错误你需要自行处理

安装Zod

npm install zod

封装中间件

在 midwares 目录下创建 zod.js:
导出了一个 ZodValid函数:该函数传入一个对象,包含了 headers, params, query 和 body 四个可选属性,分别对应请求可以传入数据的四个部分,如果需要检验,就传入定义好的检验器给需要检验的部分;ZodValid会返回一个 request handler,在处理器里面根据传入的检验器分别去进行检验,这个处理器才是最后的中间件,ZodValid其实是一个中间件工厂。我在这里取出了第一个错误,并将错误的 message 抛出,evp-express 默认直接捕捉并返回错误信息,我这样写是为了让读者对错误信息能看的更清楚,非特定场景下,不一定要返回这样细致的错误信息,可以抛出统一错误信息

const { z } = require("zod");

/**
 * @typedef {{
 * code: string;
 * expected: string;
 * received: any;
 * path: string[];
 * message: string;
 * }} MyZodError
 */

/**
 * @param {z.ZodError} errors 
 * @reutrns
 */
function selFirstError(errors) {
  /**
   * @type {MyZodError[]}
   */
  const errs = JSON.parse(errors);
  return errs[0];
}

module.exports = {
  /**
   * 
   * @param {{
   * headers: z.ZodObject|undefined;
   * params: z.ZodObject|undefined;
   * query: z.ZodObject|undefined;
   * body: z.ZodObject|undefined;
   * }} param0 
   * @returns
   */
  ZodValid: ({headers, params, query, body})=>{
    /**
     * @type {import("express").RequestHandler}
     */
    const handler = (req,res,next)=>{
      if (headers) {
        const result = headers.safeParse(req.headers);
        if (!result.success) {
          throw new Error(selFirstError(result.error).message)
        }
      }
      if (params) {
        const result = params.safeParse(req.params);
        if (!result.success) {
          throw new Error(selFirstError(result.error).message)
        }
      }
      if (query) {
        const result = query.safeParse(req.query);
        if (!result.success) {
          throw new Error(selFirstError(result.error).message)
        }
      }
      if (body) {
        console.log(req.body);
        const result = body.safeParse(req.body);
        if (!result.success) {
          throw new Error(selFirstError(result.error).message)
        }
      }
      next();
    }
    return handler;
  }
}

使用中间件

改写 router/index.js:定义2个路由,一个 GET 一个 POST,GET接口检验 query 参数种的 name 字段,POST接口检验请求体数据中的 name, pass 和 email,由于请求发送的数据格式使用了 Json,所以我们的ZodValid要放在转换请求体格式的Json中间件之后。

const { Router } = require('express');
const logger = require('../utils/logger');
const Resp = require('../model/resp');
const { ZodValid } = require('../midwares/zod');
const { z } = require('zod');
const { Json } = require('../midwares/bodyParser');

const router = Router();

router.get('/', ZodValid({
  query: z.object({ name: z.string().nonempty("name cannot be empty") })
}), async (req, res, next) => {
  const name = req.query.name;
  logger.info(`Hello World! ${name}`);
  res.json(Resp.ok(`Hello World! ${name}`, 1, null));
});


router.post('/', Json, ZodValid({
  body: z.object({ 
    name: z.string().nonempty("name cannot be empty").min(8, "name at least 8 length"),
    pass: z.string().nonempty("password cannot be empty").min(8, "password at least 8 lenght"),
    email: z.string().email("email is invalid") })
}), async (req, res, next) => {
  const name = req.body.name;
  logger.info(`Hello World! ${name}`);
  res.json(Resp.ok(`Hello World! ${name}`, 1, null));
});

module.exports = router;

测试

调整请求数据,分别访问这两个接口,你将得到类似这样的结果:

{
  "code": 500,
  "msg": "name cannot be empty",
  "data": null,
  "symbol": 0,
  "type": "Bad Request"
}
{
    "code": 500,
    "msg": "email is invalid",
    "data": null,
    "symbol": 0,
    "type": "Bad Request"
}

本文仅演示了 Zod.js 最基础的用法,还有z.optional可选,z.nullish可空,z.refine自定义逻辑等api,更详细更高阶的用法可以查看 Zod官方手册:https://zod.dev/README_ZH文章来源地址https://www.toymoban.com/news/detail-645207.html

下一节-集成Redis

到了这里,关于【Express.js】使用zod检验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Express.js】请求类型

    本节将介绍常见的http请求方式,并站在后端的角度初步感受它们的不同点 GET 意图是 获取 ,不会对服务器上的数据产生影响,将要携带的数据放在 URL 上,通常不带请求体,带了也不一定兼容 POST 意图是 提交 ,通常用于修改和新增服务器上的数据,偏向 新增 ,路径定位较

    2024年02月09日
    浏览(43)
  • 【Node.js】Express-Generator:快速生成Express应用程序的利器

    在Node.js世界中,Express是一个广泛使用的、强大的Web应用程序框架。它为开发者提供了一系列的工具和选项,使得创建高效且可扩展的Web应用程序变得轻而易举。然而,对于初学者来说,配置和初始化Express应用程序可能会有些困难。为了解决这个问题,Express团队推出了一款名

    2024年02月10日
    浏览(55)
  • 【Express.js】软件测试

    本节介绍如何在 express.js 使用 Jest 进行单元测试 准备一个基础的 express 项目,本文基于 evp-express-cli 安装 Jest 生成 Jest 配置 创建测试文件,以 .test.js 后缀命名,Jest 在运行期间会自动查找并执行符合 *.test.js 命名的文件,为规范起见,新建一个 test 目录,存放所有的测试文件

    2024年02月13日
    浏览(36)
  • 【Express.js】微服务架构

    微服务 微服务架构是将一个单体应用程序拆分为一个个独立且保持松耦合的服务的一种架构方式,每个服务有着独立的数据库并且能独立运行部署,所有的服务最终可以被视作一个集群而进行统一管理 优缺点 从微服务的理念着手,它的优缺点绝大部分能通过与单体应用相对

    2024年02月16日
    浏览(41)
  • 【Express.js】处理请求数据

    本节将具体介绍express后端处理请求源携带数据的一些方法和技巧 很多时候我们需要处理一些类似但有操作差别或不同对象的业务,我们可以监听一段基本路径,将其中某一个段或者某几段路径作为变量,在接口中根据不同的路径变量执行不同的业务操作,这是一种REST风格比

    2024年02月11日
    浏览(39)
  • 【Express.js】集成SocketIO

    本节我们介绍在如何在 express 中集成 Socket.IO Socket.IO 算是 WebSocket 的一个超集,进行了一些封装和拓展。 创建一个 express.js 项目(本文基于evp-express-cli) 安装socket.io.js: 正常的项目都是分层的,为了避免循环依赖,本文采用代理类构造单例的方式来创建websocket服务器。 wsPro

    2024年02月13日
    浏览(37)
  • 【Express.js】集成Redis

    本节我们介绍在 express.js 中集成 redis. Redis是一个高性能的key-value内存数据库,支持事务、队列、持久化等特性,常用于高并发性能场景。 创建一个 express.js 项目(本文基于evp-express-cli) 在开发环境下安装redis 安装redis.js: 正常的项目都是分层的,为了避免循环依赖,本文采用

    2024年02月13日
    浏览(41)
  • 【Express.js】全局错误处理

    在前面几节里,我们处理异常的方法都是手动在可能引发异常的地方捕捉错误,这固然是必要的,可以有针对性得处理异常,但很多时候,有许多潜在的异常,有一句话叫永远不要相信输入的数据,你永远都不知道什么时候可能会以什么方式触发某些阴间异常从而造成系统崩

    2024年02月10日
    浏览(47)
  • 【Express.js】集成RabbitMQ

    本节我们介绍在 express.js 中集成 rabbitmq. RabbitMQ 是一个消息队列中间件,常用于请求削峰,事务的队列处理,事件订阅机制的实现等。 创建一个 express.js 项目(本文基于evp-express-cli) 在开发环境下安装rabbitmq 安装amqplib.js: 正常的项目都是分层的,为了避免循环依赖,本文采用

    2024年02月13日
    浏览(34)
  • 【Express.js】集成Websocket

    本节我们介绍在如何在 express 中集成 websocket。 WebSocket 服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。 创建一个 express.js 项目(本文基于evp-express-cli) 安装ws.js: (本教程使用更通用的ws.js,有

    2024年02月13日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包