代码地址:https://github.com/changeclass/Node_Blog.git

# 接口设计

image-20201004110928069

# 初始化路由

这一步实现上述接口。实现的只是一个简单的路由,并不会真的处理数据。即只实现路由的处理。

入口文件为 /bin/www.js ,即创建服务器时,传入一个核心路由(入口)的函数。

在这个核心路由中,负责汇集所有分路由(blog 相关、user 相关)。

const handleBlogRouter = require('./src/router/blog')
const handleUserRouter = require('./src/router/user')
const serverHandle = (req, res) => {
    // 设置返回格式 JSON
    res.setHeader('Content-type', 'application/json')
    //  处理请求路径
    // 请求地址
    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 = serverHandle

接下来只需要处理每个分路由即可。

大致逻辑如下,分路由几乎相同。

const handleBlogRouter = (req, res) => {
    // 请求方式
    const method = req.method
    // 获取博客列表
    if (method === 'GET' && req.path === '/api/blog/list') {
        return {
            msg: '这是获取博客列表的接口'
        }
    }
}
module.exports = handleBlogRouter

# 规范返回格式

为了方便规范返回格式,创建一个模型类,用于创建返回信息。

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
}

成功信息与失败信息继承于信息。信息包含的属性有 data 与 message。失败编号为 - 1,成功编号为 0。然后将其导出,即可创建对象后将其返回。

# 开发路由 —— 博客列表

返回博客列表应该在路由处获取,但为了降低耦合,将获取逻辑写入 controller 文件夹下的 blog。js 文件。于是 src 文件就变成了如图。

image-20201004163807774

由于未连接数据库,因此返回数据也是假数据,但格式正确。

const getList = (author, keyword) => {
    // 返回假数据,但格式正确
    return [
        {
            id: 1,
            title: '标题A',
            content: '内容A',
            createTime: 1601799298039,
            author: '张三'
        },
        {
            id: 2,
            title: '标题B',
            content: '内容B',
            createTime: 1601799329721,
            author: '李四'
        }
    ]
}
module.exports = {
    getList
}

至此,已经完成了获取数据的逻辑,并将其导出。只需要在路由处调用此方法即可获取到数据。

// 获取博客列表
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)
}

image-20201004163929822

# 开发路由 —— 博客详情

与上面的道理相似。

const getDetail = (id) => {
    // 返回假数据
    return {
        id: 1,
        title: '标题A',
        content: '内容A',
        createTime: 1601799298039,
        author: '张三'
    }
}
module.exports = {
    getList,getDetail
}

接下来在路由处调用此方法即可获取到假数据。

# 获取 POST Data

由于 POST Data 的获取不是简单的逻辑,因此单独在 app.js 文件夹里分离一个函数用于获取。但是获取为异步获取,因此使用 Promise。

// 处理 post data
const getPostData = (req) => {
    return new Promise(((resolve, reject) => {
        if (req.method !== 'POST') {
            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))
        })
    }))
}

只接受 JSON 格式的请求数据。接下来处理路由的逻辑应该全部放在处理 POST Data 之后。

getPostData(req).then(postData=>{
    req.body = postData
    // 处理 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()
})

# 开发路由 —— 新建和修改

新建和修改的路由也比较简单,同样的返回假数据。

// 新建博客
const newBlog = (blogData = {}) => {
    //blogData 是一个博客对象,
    return {
        id: 3 // 表示新建博客的数据表 ID
    }
}
// 更新博客
const updataBlog = (id, blogData = {}) => {
    //id 为更新博客的 ID
    //blogData 为更新的对象
    return true
}

接下来只需要在路由逻辑中调用此方法获取数据即可

// 新建一篇博客
if (method === 'POST' && req.path === '/api/blog/new') {
    const data = newBlog(req.body)
    return new SuccessModel(data)
}
// 更新一篇博客
if (method === 'POST' && req.path === '/api/blog/update') {
    const result = updataBlog(id,req.body)
    if(result){
        return  new SuccessModel(result)
    }else{
        return new ErrorModel("更新失败")
    }
}

# 开发路由 —— 删除和登录

删除逻辑与新建逻辑相似。

const delBlog = (id)=>{
    //id 就是要删除博客的 ID
    return true
}
// 删除一篇博客
if (method === 'POST' && req.path === '/api/blog/del') {
    const result = delBlog(id)
    if(result){
        return  new SuccessModel(result)
    }else{
        return new ErrorModel("删除失败")
    }
}

为了区分,user 的逻辑在新建一个 controller,用于编写处理 user 相关的逻辑。

const loginCheck = (username,password)=>{
    // 假数据
    if(username==='zhangsan'&&password==='123'){
        return true
    }
}
module.exports = {
    loginCheck
}

接下来在 user 的路由中进行调用此方法。

const {loginCheck} = require('../controller/user')
const {SuccessModel, ErrorModel} = require('../model/resModel')
const handleUserRouter = (req, res) => {
    // 请求方式
    const method = req.method
    // 登陆
    if (method === 'POST' && req.path === '/api/user/login') {
        const {username,password} = req.body
        const result = loginCheck(username,password)
        if(result){
            return  new SuccessModel(result)
        }else{
            return new ErrorModel("登陆失败")
        }
    }
}
module.exports = handleUserRouter
更新于

请我喝[茶]~( ̄▽ ̄)~*

Dreamy.TZK 微信支付

微信支付

Dreamy.TZK 支付宝

支付宝