美文网首页
Node零基础入门到服务端程序 -- 第四章

Node零基础入门到服务端程序 -- 第四章

作者: KatherineLo | 来源:发表于2020-07-26 20:28 被阅读0次

第四章 入参和验证入参

之前我们写了一个接口,把所有的书本数据都提供给了api,现在我们再写一个接口,通过丰富之前的代码,用于搜索书本。

搜索功能,我们知道,大约是在输入框中填入某些内容,然后接口返回与内容相关的数据,那么这里就涉及到一个内容,就是通过api请求传入服务端的内容,我们称之为入参。入参在进入服务端之前,我们需要验证它们的格式是否符合我们设定的要求,不符合我们要求的入参规则的请求我们就可以直接返回报错,不需要处理它们了。

那么验证入参是否合格我们就需要用到一个新的包:Joi

npm install joi --save

tips: Joi 文档

src/router.js

const Router = require('koa-router');
const router = new Router();
// 这是一个用于验证入参是否正确的包
const Joi = require('joi');
// 创建一个函数用于验证入参是否正确
const { validatorInterceptor } = require('./lib');
const { BookController } = require('./controllers/book-controller');
router.get('/', ctx => ctx.body = 'Web API Running Successfully.');
router.get('/api/books', BookController.get);
// 用于验证入参
const bookSearchSchema = {
    query: Joi.object().keys({
        // 这里要求入参可以有名为search_text的参数,且必须是字符串
        text: Joi.string(),
    }),
};
// 第一个参数依旧是路由地址,第二个参数我们验证入参是否合格的函数放在这里,第三个参数是controller执行层
router.get('/api/book/search', validatorInterceptor(bookSearchSchema), BookController.get);
module.exports = router;

上面我们创建了一个用于验证入参是否合格的函数,由于这个函数为公用方法,那么我们创建一个lib文件夹,并把它写在index.js里面

src/index.js

// 这是一个在node中非常常用且好用的包,用于处理各种数据(如json,数组等)重组,使用npm install lodash安装
const _ = require('lodash');
// 这个函数同样要使用到Joi,所以依然引入它
const Joi = require('joi');
exports.validatorInterceptor = async (schemas, options) => {
    // 这里我们给validatorInterceptor返回一个函数
    return async (ctx, next) => {
        try {
            // 将传入的schemas的key全部取出,并循环它们
            for (const key of _.keys(schemas)) {
                // 使用validate方法验证每一个key是否符合要求
                await Joi.validate(_.get(ctx.request, key), _.get(schemas, key), options || {});
            }
        }
        // 如果不符合要求,则直接报400错误
        catch (err) {
            ctx.throw(400, `validation failed on: ${err.message}`);
        }
        // 如果没有问题,则下一步
        await next();
    };
}

tips: lodash 文档

刚才可以发现,搜索api我们使用的还是get方法,那么现在我们就来改装一下这个方法

src/controllers/book-controller.js

const { BookService } = require('../services/book-service');
class BookController {
    static async get(ctx) {
        // 我们将入参从ctx.request.query中取出
        const searchText = ctx.request.query.text;
        const bookService = new BookService();
        // 传入service方法中使用
        const res = await bookService.get(searchText);
        ctx.body = res;
    }
}
module.exports = { BookController };

接着修改service方法

src/services/book-services.js

const bookModel = require('../schemas/book-schema');
class BookService {
    // 这个函数的入参为刚才controller层传入的搜索内容
    async get(searchText) {
        // 我们设置一个默认的内容,就是当接口什么搜索内容都没有传入的时候,我们默认返回所有书本给接口
        const query = {};
        // 当有搜索内容传入的时候
        if (searchText) {
            // 我们希望数据库无论是书本名称还是作者,有相关的文字内容就可以将其搜索出来
            // 这里的$or和后面的内容写法都是mongo搜索时的写法,有不了解的同学可以查看mongo相关文档学习
            query.$or = [{name: new RegExp(searchText)}, {author: new RegExp(searchText)}];
        }
        // 和之前一样,查询数据,然后将结果返回
        const res = await bookModel.find(query);
        return res;
    }
}
module.exports = { BookService };

接下来,启动程序,开始验证我们的代码编写成果

node src/server.js

打开浏览器

首先无任何参数,我们希望返回所有的书本数据:http://localhost:3000/api/book/search

图片

当参数错误时:http://localhost:3000/api/book/search?aaa=111

图片

搜索书本名称,三体:http://localhost:3000/api/book/search?text=三体

图片

搜索作者名称,村上春树:http://localhost:3000/api/book/search?text=村上春树

图片

搜索不完全的书本名称,挪威:http://localhost:3000/api/book/search?text=挪威

图片

全部成功,我们的搜索接口,就是这么简单 __

本文已完成电子书《Node零基础入门到服务端程序》电子书(含教程内项目代码)/ 10元,购买链接:https://mianbaoduo.com/o/bread/mbd-Z5WZk5o=
ps:前九章(本书共计十三章)内容会在这里陆续更新。

相关文章

网友评论

      本文标题:Node零基础入门到服务端程序 -- 第四章

      本文链接:https://www.haomeiwen.com/subject/wdeglktx.html