Node.js 从零开发web server博客项目--controller与返回模型

上篇博客记录了《Node.js 从零开发web server博客项目》项目的初始化及初步的项目结构规划。

开篇将继续接着上篇中的项目内容,介绍返回内容的设计与解析postData。

对于接口返回的内容结构,我们通过一个创建一个resModel.js进行说明。新建model/resModel.js,

class BasicModel{
    constructor(data, message){
        if(typeof data === "string"){
            this.data = data;
            data = null;
            message = null;
        }
        if(data){
            this.data = data;
        }
        if(message){
            this.message = message;
        }
    }
}
class SuccessModel extends BasicModel{
    constructor(data,message){
        super(data,message);
        this.errorno = 0;
    }
}

class ErrorModel extends BasicModel{
    constructor(data,message){
        super(data,message);
        this.errorno = -1;
    }
}
module.exports = {
    SuccessModel,
    ErrorModel
}

为返回的数据内容创建一个基类,包含data和message。返回成功及返回错误都继承这个基类。

我们将在router文件中使用,比如在获取博客列表接口中,我们使用方式如下:

    if(method==="GET" && path==="/api/blog/list"){
        // 获取参数
        const keyword = req.query.keyword || '';
        const author = req.query.author || '';

        const listData = getList(keyword,author);
        return new SuccessModel(listData,'success');
    }

注意到,相比于上次博客中介绍的接口,我们新增一个获取博客列表的方法,getList,并传入关键字及作者作为参数。

接口中处理数据的方法,我们放在controller/blog.js中,在blog.js中专门处理与博客相关数据的处理。

const getList = (keyword, author) => {
    return [{
        id:1,
        title:'标题1',
        content:'内容',
        createTime:12345678,
        author:'张三'
    }];
}

const getBlog = (id) => {
    return {
        id:1,
        title:'标题1',
        content:'内容',
        createTime:12345678,
        author:'张三'
    };
}
const newBlog = (blogData)=>{
    return {
        id:3
    }
}

const updateBlog = (id, blogData) => {
    return true;
}
module.exports = {
    getList,
    getBlog,
    newBlog,
    updateBlog
};

上面贴出的代码描述了四个接口的处理过程,到目前为止,我们的接口仍然未与数据库进行交互,都是直接返回写死的内容。

截止目前为止,我们的项目结构如下图所示。

Node.js 从零开发web server博客项目--controller与返回模型_第1张图片

上面我们举了一个get请求的接口--获取博客列表,参数都是放在链接上,对于get请求,我们项目通过querystring解析search的参数列表,放在req.query中。

对于post请求,我们需要等待post数据接收完毕,放在req.body中。这样我们就把入参比较同意地放在req的各自参数中。第一篇博客有提到post的数据结合req.on('data',(data)=>{})与req.on('end',()=>{})获取,而这个过程是异步的,所以我们用Promise对这个过程进行处理。

const getPostData = (req) => {
    const promise = new Promise(
        (resolve,reject) => {
            if(req.method === "GET"){
                resolve({});
                return;
            }
            if(req.headers['content-type']!=='application/json'){
                resolve({});
                return;
            }
            let postData = '';
            req.on('data',(chunk)=>{
                postData += chunk.toString();
            });
            req.on('end',()=>{
                if(!postData) {
                    resolve({});
                    return;
                }
                resolve(
                    JSON.parse(postData)
                );
            })
        }
    );
    return promise;
}

getPostData将对req中的post内容进行处理,并返回。由于项目限制传参必须是json格式,所以非json内容postdata返回为空对象。

对post数据的处理,我们也是放在app.js中进行的。处理完成之后,再调用相应的路由处理方法。

getPostData(req).then(
        (postData) => {
            req.body = postData;
            const userLogin = userRouterHandler(req, res);
            if(userLogin){
                res.end(JSON.stringify(userLogin));
                return;
            }
           const blogData = blogRouterHandler(req, res);
           if(blogData){
               res.end(JSON.stringify(blogData));
               return;
           }
        
           res.writeHead(404, {"Content-type":"text/plain"});
           res.write("404 Not Found");
           res.end();
        
        }
    )

到目前为止,项目已经分了这么几个层次

1、www.js,项目入口文件,主要是创建httpServer,并监听端口

2、app.js,serverHandler,主要对req,res进行处理,获取path用于api匹配,获取query参数,获取post数据,并调用router中的相关处理方法

3、router部分,主要根据不同模块处理不同的api入口,根据req.path进行匹配分发,调用api的实现方法。获取查询参数与post数据,并将这些作为controller层的各个业务处理函数的入参。

4、controller部分,这部分主要实现各个api对应的业务逻辑实现,输入为router中的获取的参数。

5、model层,公用的model,如返回数据模型,含有data,message,errorno等信息

到目前为止,controller中的业务实现逻辑并未涉及到数据库的内容,目前还是静态数据,接下来将介绍数据库连接,数据库操作等内容。

你可能感兴趣的:(NodeJs)