手把手搭建koa2后端服务器-请求参数与数据校验

2022-04-27 16:15:00 浏览数 (2)

安装库 koa-body 和 async-validator

代码语言:javascript复制
yarn add koa-body async-validator

koa-body 引入配置

koa-body 可以代替代替 koa-bodyparser 和 koa-multer 处理请求参数和文件上传

可参考文档: http://www.ptbird.cn/koa-body.html

代码语言:javascript复制
// src/app.ts
import KoaBody from 'koa-body';

app.use(
  KoaBody({
    // 启用表单解析,可以支持文件上传
    multipart: true,
    formidable: {
      // 文件上传路径
      uploadDir: './uploads',

      // 保持文件的扩展名
      keepExtensions: true,

      // 文件上传大小限制,默认5M
      maxFieldsSize: 5 * 1024 * 1024,

      // 保持文件的扩展名
      onFileBegin: (name, file) => {
        // 文件上传前的设置
        // console.log(name, file);
      },
    },
  }),
);

async-validator 引入配置

创建表单验证模块 src/utils/validate.ts

代码语言:javascript复制
import type { Context } from 'koa';
import Schema, { Value, Rules } from 'async-validator';

/**
 * 请求表单验证
 * @param ctx
 * @param rules
 * @returns
 */
const validate = async <T extends Value>(
  ctx: Context,
  rules: Rules,
): Promise<{ data: T; error: string }> => {
  const validator = new Schema(rules);
  let data: any = null;
  switch (ctx.method) {
    case 'GET':
      data = ctx.query;
      break;
    case 'POST':
      data = ctx.request.body;
      break;
    case 'PUT':
      data = ctx.request.body;
      break;
    case 'DELETE':
      data = ctx.query;
      break;
    default:
      data = ctx.request.body;
  }

  return await validator
    .validate(data)
    .then(() => {
      return {
        data: data as T,
        error: '',
      };
    })
    .catch((err) => {
      return {
        data: {} as T,
        error: err.errors[0].message,
      };
    });
};

export default validate;

koa-body 默认只解析 [POST, PUT, PATCH],不解析 [GET, HEAD, DELETE]

创建基础逻辑处理结构

  • 创建 controller目录:src/controller
  • 创建通用逻辑处理 common 目录:src/constroller/common
  • 创建校验规则文件:src/controller/common/rules.ts
代码语言:javascript复制
import type { Rules } from 'async-validator';

export const loginRules: Rules = {
  username: {
    type: 'string',
    min: 8,
    required: true,
    message: '用户名或密码错误',
  },
  password: {
    type: 'string',
    min: 8,
    required: true,
    message: '用户名或密码错误',
  },
};
  • 创建类型定义文件:src/controll/common/types.ts
代码语言:javascript复制
export interface LoginParam {
  username: string;
  password: string;
}
  • 创建统一响应处理文件:src/utils/response.ts
代码语言:javascript复制
import type { Context } from 'koa';

/**
 * @description 成功响应
 * @param ctx
 * @param data
 * @param message
 */
export const success = (
  ctx: Context,
  data: any,
  message: string | undefined = undefined,
) => {
  ctx.body = {
    code: 0,
    data,
    message,
  };
};

/**
 * @description 失败响应
 * @param ctx
 * @param message
 */
export const error = (ctx: Context, message: string) => {
  ctx.body = {
    code: -1,
    message,
  };
};
  • 创建登录逻辑处理文件:src/controll/common/view.ts
代码语言:javascript复制
import { Context } from 'koa';
import validate from '../../utils/validate';
import { LoginParam } from './types';
import { loginRules } from './rules';
import response from '../../utils/response';

class IndexController {
  async login(ctx: Context) {
    const { data, error } = await validate<LoginParam>(ctx, loginRules);
    if (error) {
      response.error(ctx, error);
      return;
    }

    response.success(ctx, data);
  }
}

export default new IndexController();

按照以上步骤,我们将创建第一个逻辑处理模块,并且完善了项目结构,后面的业务逻辑处理我们就按照这种结构开发。

系列文章:

  1. 手把手搭建koa2后端服务器-项目初始化

0 人点赞