美文网首页
跟我一起学NodeJs之环境搭建,路由初始化,应用分层,路由开发

跟我一起学NodeJs之环境搭建,路由初始化,应用分层,路由开发

作者: 喜剧之王爱创作 | 来源:发表于2020-04-08 10:49 被阅读0次
u=4104387483,4024841696&fm=26&gp=0.jpg

上一节,我们将了NodeJS的安装,server的创建、debugger等,想要满足开发,我们还是要接着往下看,那么,我们直奔主题!

项目实战(原生环境搭建)

依赖包
  • cross-env:提供兼容Win,Mac,Linux不同系统的环境变量
  • nodemon:监控NodeJS文件变化,实现自动编译,不用每次修改文件后手动重启服务

可通过下面代码进行安装

yarn add nodemon cross-env --save-dev
创建目录结构
  1. 执行npm init -y,创建一个初始化的npm环境,用来将来安装一些依赖包,生成package.json文件
  2. 项目目录下创建'bin'文件夹,一般存放可执行文件,并在其下层创建'www.js'文件,在这里我们写一些Server相关的代码,即server
  3. 在项目目录下创建app.js,在这里我们用来写我们的业务代码
写代码
//www.js
const http = require('http')
const PORT = 8000
const serverHandel = require('../app')
const server = http.createServer(serverHandel)
server.listen(PORT)
console.log('success')
//app.js
const serveHandel = (req, res) => {
    //设置返回格式为JSON
    res.setHeader('Content-type', 'application/json')
    const resData = {
        name:'张三',
        age: 18,
        env: process.env.NODE_ENV
    }
    res.end(
        JSON.stringify(resData)
    )

}
module.exports = serveHandel
//在安装完以上'nodemon 和cross-env'后,需要配置一下node指令,和主文件,如下
  "main": "bin/www.js",
  "scripts": {
    "dev": "cross-env NODE_ENV=dev nodemon ./bin/www.js",
    "prd": "cross-env NODE_ENV=production nodemon ./bin/www.js"
  },

上面我将server代码,业务代码抽离开,使得项目更加易于维护,我们可以在app.js里面进行各种配置和解析,并且可以将不同的方法相互引用,而www.js只放心做server端的事。

到这里,一个基础的NodeJS项目环境就搭建完成了,是不是很简单呢

开发

路由初始化

首先需要注意

  • 接口,是通过路由实现的

上面我们搭建了基本的开发环境,也将server层代码和业务代码分离,但毕竟业务是复杂的我们不能把业务代码都写在app.js里面,所以这里仍然需要做个拆分,一般我们采用的方案是在“bin”同级新建“src”文件夹,其中的每个人间代表一类接口,然后我们再通过模块化将其引入到app.js中,这样,我们就可以不同的业务代码写在不同文件件里,一些公共的配置也可以在app.js里面进行全局配置,这样的代码将拆分的更加简单

一般的,我们需要先将接口调通,再去处理其具体数据,下面我将改造后的app.js和其中一个业务代码模块贴出来,同学们也可以跟着这个节奏进行扩展

//app.js
const handleBlogRouter = require('./src/router/blog')
const handleUserRouter = require('./src/router/user')

const serveHandel = (req, res) => {
    //设置返回格式为JSON
    res.setHeader('Content-type', 'application/json')
    //设置path
    const url = req.url
    req.path = url.split('?')[0]
    //处理blog路由
    const blogData = handleBlogRouter(req, res)
    if(blogData) {
        res.end(
            JSON.stringify(blogData)
        )
        return
    }
    //处理user路由
    const userData = handleUserRouter(req,res)
    if(userData) {
        res.end(
            JSON.stringify(userData)
        )
        return
    }
    //未命中路由返回404
    res.writeHead(404, {"Content-type": "text/plain"})
    res.write("404 Not Found\n")
    res.end()

}
module.exports = serveHandel
//其中一个业务代码
const handleBlogRouter = (req, res) => {
    const method = req.method //GET POST

    //实现接口
    //获取博客列表
    if (method === 'GET' && req.path === '/api/blog/list') {
        return {
            msg: '这是获取博客列表的接口'
        }
    }
    //获取博客详情
    if (method === 'GET' && req.path === '/api/blog/detail') {
        return {
            msg: '这是获取博客详情的接口'
        }
    }
    //新建一篇博客
    if (method === 'POST' && req.path === '/api/blog/new') {
        return {
            msg: '这是新建博客的接口'
        }
    }
    //更新一篇博客
    if (method === 'POST' && req.path === '/api/blog/update') {
        return {
            msg: '这是更新博客的接口'
        }
    }
    //删除一篇博客
    if (method === 'POST' && req.path === '/api/blog/del') {
        return {
            msg: '这是删除博客的接口'
        }
    }
}
module.exports = handleBlogRouter

这样我们就创建了不同的接口,并且可以通过浏览器或postman对其进行测试。

读到这里,我想做一个总结:

我们把不同业务代码拆分到src对应的不同文件夹下,然后通过nodejs模块化将其引入到app.js,即入口文件中,并在这里做一些全局性的配置,如响应头的设置,path的配置等,当我们调用某接口时,如:'/api/blog/detail',就会命中业务代码中的某一个逻辑,并返回对应的对象(这里我们为了先将接口测通,先返回简单对象),并最终将其作为接口响应返回,假如不能命中任何逻辑代码,则响应为404。

到这里,我们就完成了这个项目的路由初始化,下面我们就可以开发对应的路由(接口)了

路由开发

上面讲到了基础环境的搭建,Server层和业务层的分离,以及路由的初始化等,到此为止,我们已经具备了开发接口的能力(不涉及登录,不涉及数据库,只做接口的数据格式返回)

这里介绍几个概念:

  • 数据模型:一种面向对象的变成思想,用到对象继承等一些知识,我们将在后面使用数据模型来定义将来要输出的数据结构,使我们接口所输出的数据达到一个格式上的一致性,或者是易于维护的特点。
  • controller: MVC设计模式中的C,在这里,我们将用来专心的处理数据,只做和数据有关的事情,包括一些计算等等的操作。

这样,我们的项目暂时可以分为以下四层:

  • www.js:用来写Server逻辑,只关心Server的逻辑
  • app.js: 做一些基本配置,如参数的解析规则,不同接口的处理方法等,不涉及业务代码,可以看做是Server层和业务层的桥梁
  • router: 处理路由接口的逻辑,在这里我们只关心路由的都逻辑,包括匹配到路由后返回什么格式的数据等(在这里我们将用到数据模型,用来统一返回格式)
  • controller:在这里,我们只关心数据,我们可以在这里做具体的数据处理,处理参数等。

将应用分层,然后通过nodejs模块化,将各个模块关联起来,这就行程了一个成熟应用的雏形,我们可以在此基础上开发各种借口,下面我将贴出一个获取博客详情的各层代码

  1. Server层

和上面基础路由的搭建一样,这里不做说明

  1. app层

和上面基础路由的搭建一样,只加入了query解析的代码,因为这属于公共的逻辑代码

+++
req.query = querystring.parse(url.split('?')[1])
...
  1. router层

我们在上面搭建了基础的路由逻辑,即命中某一个路由,返回对应的数据,因为上面只是做初始化,使用了一些简单的“傻白甜”数据,这里我们将其具体化。

const { getList } = require('../controller/blog')
const { SuccessModel, ErrorModel } = require('../model/resModel')
    if (method === 'GET' && req.path === '/api/blog/list') {
        const author = req.query.author || ''
        const keyword = req.query.keyword || ''
        const listData = getList(author,keyword)
        return  new SuccessModel(listData)
    }

可以看到,这里我们将具体的数据处理方法getList,抽离出去,并引入了数据模型用来规范返回的数据格式。

  1. 数据模型
//我们将其建在router同级目录下的model文件夹下
class BaseModel {
    constructor(data, message) {
        if(typeof data === 'string') {
            this.message = data
            data = null
            message = null
        }
        if(data) {
            this.data = data
        }
        if (message) {
            this.message = message
        }
    }
}
class SuccessModel extends BaseModel {
    constructor(data, message) {
        super(data,message)
        this.errno  = 0
    }
}
class ErrorModel extends BaseModel {
    constructor(data, message) {
        super(data, message)
        this.errno = -1
    }
}
module.exports = {
    SuccessModel,
    ErrorModel
}

这就是数据模型,可以看出,这里用到了JS继承的一些东西,就是定义一个数据结构

  1. controller 层
//我们将其建在router同级目录下的controller文件夹下
const getList = (author, keyword) => {
    // 先返回假数据(格式是正确的)
    return [
        {
            id: 1,
            title: '标题A',
            content: '内容A',
            createTime: 1586310687741,
            author: '张三'
        },
        {
            id: 2,
            title: '标题B',
            content: '内容B',
            createTime: 1586310687741,
            author: '李四'
        }
    ]
}
module.exports = {
    getList
}

可以看到,这里我们只针对传入参数做响应的逻辑,并输出对应的参数,这里再次说明controller只关心数据的处理
于是我们访问http://localhost:8000/api/blog/list?author=zhangsan&keyword=A试试吧,是不是返回了我们想要的数据结构呢。

小结:个人认为,这一部分十分重要,我们将应用分层,不同的层写不同的代码,将各个层之间串联起来,就是一个完整的应用。好了,自己在你的编辑器上捋一捋这样的逻辑吧!

相关文章

网友评论

      本文标题:跟我一起学NodeJs之环境搭建,路由初始化,应用分层,路由开发

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